From 39801a72643054efec9853ec8eb5567f547f398d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20S=C3=B8rlie?= Date: Wed, 6 Nov 2024 10:36:33 +0100 Subject: [PATCH 001/170] refactor: Use primitives in Slate toolbar. --- src/components/SlateEditor/RichTextEditor.tsx | 2 +- .../plugins/blockPicker/SlateBlockPicker.tsx | 2 +- .../comment/inline/SlateCommentInline.tsx | 9 +- .../SlateEditor/plugins/mark/utils.tsx | 6 +- .../SlateEditor/plugins/span/index.tsx | 2 +- .../plugins/toolbar/SlateToolbar.tsx | 255 ++++++++++-------- .../plugins/toolbar/ToolbarBlockOptions.tsx | 31 ++- .../plugins/toolbar/ToolbarInlineOptions.tsx | 33 ++- .../toolbar/ToolbarLanguageOptions.tsx | 124 ++++----- .../plugins/toolbar/ToolbarMarkOptions.tsx | 23 +- .../plugins/toolbar/ToolbarTableOptions.tsx | 23 +- .../plugins/toolbar/ToolbarTextOptions.tsx | 125 +++++---- .../{ToolbarButton.tsx => ToolbarToggle.tsx} | 87 +++--- .../plugins/toolbar/handleMenuClicks.ts | 2 +- .../toolbar/toolbarDropdownComponents.tsx | 28 -- src/phrases/phrases-en.ts | 1 + src/phrases/phrases-nb.ts | 1 + src/phrases/phrases-nn.ts | 1 + 18 files changed, 409 insertions(+), 346 deletions(-) rename src/components/SlateEditor/plugins/toolbar/{ToolbarButton.tsx => ToolbarToggle.tsx} (60%) delete mode 100644 src/components/SlateEditor/plugins/toolbar/toolbarDropdownComponents.tsx diff --git a/src/components/SlateEditor/RichTextEditor.tsx b/src/components/SlateEditor/RichTextEditor.tsx index 20be860387..13a3555486 100644 --- a/src/components/SlateEditor/RichTextEditor.tsx +++ b/src/components/SlateEditor/RichTextEditor.tsx @@ -308,7 +308,7 @@ const RichTextEditor = ({
- + {isFirstNormalize && !hideSpinner ? ( diff --git a/src/components/SlateEditor/plugins/blockPicker/SlateBlockPicker.tsx b/src/components/SlateEditor/plugins/blockPicker/SlateBlockPicker.tsx index e9d766e9e9..d2b2b10b61 100644 --- a/src/components/SlateEditor/plugins/blockPicker/SlateBlockPicker.tsx +++ b/src/components/SlateEditor/plugins/blockPicker/SlateBlockPicker.tsx @@ -58,7 +58,7 @@ import { TYPE_RELATED } from "../related/types"; import { defaultTableBlock } from "../table/defaultBlocks"; import { isInTableCellHeader, isTableCell } from "../table/slateHelpers"; import { TYPE_TABLE } from "../table/types"; -import { IS_MAC } from "../toolbar/ToolbarButton"; +import { IS_MAC } from "../toolbar/ToolbarToggle"; import { TYPE_DISCLAIMER } from "../uuDisclaimer/types"; import { defaultDisclaimerBlock } from "../uuDisclaimer/utils"; import { TYPE_EMBED_BRIGHTCOVE } from "../video/types"; diff --git a/src/components/SlateEditor/plugins/comment/inline/SlateCommentInline.tsx b/src/components/SlateEditor/plugins/comment/inline/SlateCommentInline.tsx index 32b53b30a1..7a04335f72 100644 --- a/src/components/SlateEditor/plugins/comment/inline/SlateCommentInline.tsx +++ b/src/components/SlateEditor/plugins/comment/inline/SlateCommentInline.tsx @@ -6,7 +6,7 @@ * */ -import { ReactNode, useCallback, useMemo, useState } from "react"; +import { ReactNode, useCallback, useEffect, useMemo, useState } from "react"; import { Editor, Element, Path, Transforms } from "slate"; import { ReactEditor, RenderElementProps } from "slate-react"; import { PopoverRoot, PopoverTrigger } from "@ndla/primitives"; @@ -36,7 +36,12 @@ interface Props { } const SlateCommentInline = ({ attributes, editor, element, children }: Props) => { - const [open, setOpen] = useState(element.isFirstEdit); + const [open, setOpen] = useState(false); + + useEffect(() => { + setOpen(!!element.isFirstEdit); + Transforms.select(editor, ReactEditor.findPath(editor, element)); + }, [editor, element, element.isFirstEdit]); const embed: CommentMetaData = useMemo(() => { return { diff --git a/src/components/SlateEditor/plugins/mark/utils.tsx b/src/components/SlateEditor/plugins/mark/utils.tsx index 98e1dd0cc0..8ba78a0562 100644 --- a/src/components/SlateEditor/plugins/mark/utils.tsx +++ b/src/components/SlateEditor/plugins/mark/utils.tsx @@ -7,12 +7,16 @@ */ import { MouseEvent } from "react"; -import { Editor } from "slate"; +import { Editor, Transforms } from "slate"; +import { ReactEditor } from "slate-react"; import { isMarkActive } from "./index"; import { MarkType } from "../toolbar/toolbarState"; export const toggleMark = (event: KeyboardEvent | MouseEvent, editor: Editor, format: MarkType) => { event.preventDefault(); + if (!editor.selection) return; + Transforms.select(editor, editor.selection); + ReactEditor.focus(editor); const isActive = isMarkActive(editor, format); if (isActive) { diff --git a/src/components/SlateEditor/plugins/span/index.tsx b/src/components/SlateEditor/plugins/span/index.tsx index f25033406f..940a71f51b 100644 --- a/src/components/SlateEditor/plugins/span/index.tsx +++ b/src/components/SlateEditor/plugins/span/index.tsx @@ -7,7 +7,7 @@ */ import isEmpty from "lodash/isEmpty"; -import { Descendant, Editor, Element, Node, Text, Transforms } from "slate"; +import { Descendant, Editor, Element, Node, Transforms } from "slate"; import { jsx as slatejsx } from "slate-hyperscript"; import { TYPE_SPAN } from "./types"; import { createProps, reduceElementDataAttributes } from "../../../../util/embedTagHelpers"; diff --git a/src/components/SlateEditor/plugins/toolbar/SlateToolbar.tsx b/src/components/SlateEditor/plugins/toolbar/SlateToolbar.tsx index 2ad1920060..2b78faac2a 100644 --- a/src/components/SlateEditor/plugins/toolbar/SlateToolbar.tsx +++ b/src/components/SlateEditor/plugins/toolbar/SlateToolbar.tsx @@ -11,19 +11,17 @@ import { ComponentPropsWithRef, forwardRef, isValidElement, - memo, - MouseEvent, - useCallback, + ReactNode, useEffect, useMemo, useRef, + useState, } from "react"; import { Editor, Range } from "slate"; -import { useSlate, useSlateSelection } from "slate-react"; -import styled from "@emotion/styled"; -import { Portal } from "@radix-ui/react-portal"; -import { ToggleGroup, Toolbar, ToolbarSeparator } from "@radix-ui/react-toolbar"; -import { colors, spacing, misc, stackOrder } from "@ndla/core"; +import { useFocused, useSlate, useSlateSelection } from "slate-react"; +import { usePopoverContext } from "@ark-ui/react"; +import { PopoverContent, PopoverRoot } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { ToolbarBlockOptions } from "./ToolbarBlockOptions"; import { ToolbarInlineOptions } from "./ToolbarInlineOptions"; import { ToolbarLanguageOptions } from "./ToolbarLanguageOptions"; @@ -39,56 +37,40 @@ import { import { ToolbarTableOptions } from "./ToolbarTableOptions"; import { ToolbarTextOptions } from "./ToolbarTextOptions"; -const ToolbarContainer = styled(Toolbar)` - position: absolute; - align-self: center; - opacity: 0; - transition: opacity 0.75s; - border: 1px solid ${colors.brand.tertiary}; - border-radius: ${misc.borderRadius}; - background-color: ${colors.white}; - padding: ${spacing.xsmall}; - overflow: visible; - display: flex; - flex-direction: column; - gap: ${spacing.xsmall}; - pointer-events: auto !important; -`; - -const StyledToolbarRow = styled.div` - display: flex; -`; - -const StyledToolbarSeparator = styled(ToolbarSeparator)` - margin: 0 ${spacing.xxsmall}; - width: 1px; - background-color: ${colors.brand.greyLight}; - &:last-child { - display: none; - } -`; - -export const StyledToggleGroup = styled(ToggleGroup)` - display: flex; - gap: ${spacing.xxsmall}; -`; - -const showToolbar = (toolbar: HTMLElement, modalRef: HTMLElement | null) => { - toolbar.style.display = "flex"; - const native = window.getSelection(); - if (!native) { - return; - } - const range = native.getRangeAt(0); - const rect = range.getBoundingClientRect(); - toolbar.style.opacity = "1"; - toolbar.style.zIndex = `${modalRef ? stackOrder.modal + stackOrder.popover : stackOrder.popover}`; - - const left = rect.left < toolbar.offsetWidth / 2 ? 10 : rect.left + rect.width / 2 - toolbar.offsetWidth / 2; - - toolbar.style.top = `${rect.top + window.scrollY - toolbar.offsetHeight}px`; - toolbar.style.left = `${left}px`; -}; +const ToolbarContainer = styled(PopoverContent, { + base: { + border: "1px solid", + isolation: "isolate", + borderColor: "stroke.subtle", + padding: "4xsmall", + textStyle: "body.medium", + userSelect: "none", + zIndex: "dropdown", + rowGap: "xsmall", + display: "grid", + "& > *": { + paddingInline: "3xsmall", + }, + wide: { + gridTemplateColumns: "repeat(6, auto)", + "& > :not(:last-child)": { + borderRight: "1px solid", + }, + }, + tabletWideToWide: { + gridTemplateColumns: "repeat(3, auto)", + "& > :not(:last-child):not(:nth-child(3n))": { + borderRight: "1px solid", + }, + }, + tabletWideDown: { + gridTemplateColumns: "repeat(2, auto)", + "& > :not(:last-child):not(:nth-child(2n))": { + borderRight: "1px solid", + }, + }, + }, +}); export interface ToolbarCategoryProps { options: ToolbarValue[]; @@ -99,57 +81,83 @@ interface Props { areaOptions: AreaFilters; hideToolbar?: boolean; } +const checkHasSelectionWithin = (el?: Element | null) => { + if (!el) return false; + + const selection = el.ownerDocument.getSelection(); + if (!selection?.rangeCount) return false; + + const range = selection.getRangeAt(0); + return !range.collapsed && el.contains(range.commonAncestorContainer); +}; const SlateToolbar = ({ options: toolbarOptions, areaOptions, hideToolbar: hideToolbarProp }: Props) => { - const portalRef = useRef(null); const selection = useSlateSelection(); const editor = useSlate(); - const modalRef = useRef(null); - const hasCheckedForModal = useRef(false); - - const hideToolbar = useMemo(() => { - return ( - !selection || - hideToolbarProp || - Range.isCollapsed(selection) || - Editor.string(editor, selection) === "" || - !editor.shouldShowToolbar() - ); - }, [hideToolbarProp, editor, selection]); + const toolbarRef = useRef(null); + const editorWrapperRef = useRef(null); + const editorFocused = useFocused(); + const [open, setOpen] = useState(false); + const [hasSelectionWithin, setHasSelectionWithin] = useState(false); + const [hasMouseDown, setHasMouseDown] = useState(false); useEffect(() => { - const portal = portalRef.current; - if (!portal) return; - if (!hasCheckedForModal.current) { - modalRef.current = document.querySelector('[role="dialog"]') as HTMLDivElement; - hasCheckedForModal.current = true; + if (toolbarRef.current) { + editorWrapperRef.current = toolbarRef.current.closest("[data-slate-wrapper]") as HTMLDivElement; } - showToolbar(portal, modalRef.current); + }, []); + + useEffect(() => { + const onSelect = () => { + setHasSelectionWithin(!!checkHasSelectionWithin(editorWrapperRef.current)); + }; + + document.addEventListener("selectionchange", onSelect); return () => { - if (portal && modalRef.current) { - portal.removeAttribute("style"); - hasCheckedForModal.current = false; - } + document.removeEventListener("selectionchange", onSelect); }; - }); + }, []); - // This effect only affects the toolbar when it exists inside a modal. It handles placing the toolbar when - // a modal is scrollable. useEffect(() => { - if (hideToolbar) return; - const initialScroll = modalRef.current?.scrollTop ?? 0; - const onModalScroll = () => { - if (!modalRef.current || !portalRef.current) return; - const scroll = initialScroll - modalRef.current.scrollTop; - portalRef.current.style.transform = `translateY(${scroll}px)`; + const element = editorWrapperRef.current?.querySelector("[data-slate-editor]"); + if (!element) return; + const onMouseDown = () => { + setHasMouseDown(true); }; - modalRef.current?.addEventListener("scroll", onModalScroll); + + const onMouseUp = () => { + setHasMouseDown(false); + }; + + element.addEventListener("mousedown", onMouseDown); + document.addEventListener("mouseup", onMouseUp); return () => { - modalRef.current?.removeEventListener("scroll", onModalScroll); + element.removeEventListener("mousedown", onMouseDown); + document.removeEventListener("mouseup", onMouseUp); }; - }, [hideToolbar]); + }, []); - const onMouseDown = useCallback((e: MouseEvent) => e.preventDefault(), []); + useEffect(() => { + const nonCollapsed = selection && !Range.isCollapsed(selection); + if (nonCollapsed && hasSelectionWithin && !hasMouseDown) { + setOpen(true); + } else if (!document.activeElement?.closest('[role="dialog"]')) { + setOpen(false); + } + }, [editor, editor.selection, editorFocused, hasMouseDown, hasSelectionWithin, selection]); + + const hideToolbar = useMemo(() => { + return ( + hasMouseDown || + !open || + !selection || + !hasSelectionWithin || + hideToolbarProp || + Range.isCollapsed(selection) || + Editor.string(editor, selection) === "" || + !editor.shouldShowToolbar() + ); + }, [hasMouseDown, open, selection, hasSelectionWithin, hideToolbarProp, editor]); const options = useMemo(() => { if (hideToolbar) return; @@ -158,15 +166,26 @@ const SlateToolbar = ({ options: toolbarOptions, areaOptions, hideToolbar: hideT options: toolbarOptions, areaOptions, }); - }, [areaOptions, editor, hideToolbar, toolbarOptions, selection]); - - if (hideToolbar) { - return null; - } + }, [hideToolbar, editor, selection, toolbarOptions, areaOptions]); return ( - - + + + - + ); }; -const ToolbarRow = forwardRef>(({ children, ...rest }, ref) => { - const count = Children.count(children); +const ToolbarRepositioner = forwardRef>((props, ref) => { + const { open, reposition } = usePopoverContext(); + const selection = useSlateSelection(); + + useEffect(() => { + if (open) { + reposition(); + } + }, [open, reposition, selection]); - // Do not draw separators for categories with only disabled and hidden options + return
; +}); + +const ToolbarRow = ({ children }: { children: ReactNode }) => { + // Do not render categories with only disabled and hidden options const validChildren = Children.toArray(children).filter( (child) => isValidElement>(child) && !child.props.options?.every((el) => el.hidden === true), ); - return ( - - {Children.map(validChildren, (child, i) => ( - <> - {child} - {i < count && } - - ))} - - ); -}); + return validChildren; +}; -export default memo(SlateToolbar); +export default SlateToolbar; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarBlockOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarBlockOptions.tsx index 18ae74cb1f..5d2c668b6b 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarBlockOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarBlockOptions.tsx @@ -8,12 +8,11 @@ import isEqual from "lodash/isEqual"; import { useCallback } from "react"; -import { Editor, Element } from "slate"; -import { useSlate, useSlateSelector } from "slate-react"; -import { ToggleItem } from "@radix-ui/react-toolbar"; -import { StyledToggleGroup, ToolbarCategoryProps } from "./SlateToolbar"; -import ToolbarButton from "./ToolbarButton"; +import { Editor, Element, Transforms } from "slate"; +import { ReactEditor, useSlate, useSlateSelector } from "slate-react"; +import { ToolbarCategoryProps } from "./SlateToolbar"; import { BlockType } from "./toolbarState"; +import { ToolbarToggleButton, ToolbarToggleGroupRoot } from "./ToolbarToggle"; import toggleBlock from "../../utils/toggleBlock"; import { toggleDefinitionList } from "../definitionList/utils/toggleDefinitionList"; import { toggleList } from "../list/utils/toggleList"; @@ -53,6 +52,9 @@ export const ToolbarBlockOptions = ({ options }: ToolbarCategoryProps const onClick = useCallback( (type: BlockType) => { + if (!editor.selection) return; + Transforms.select(editor, editor.selection); + ReactEditor.focus(editor); if (type === "definition-list") { toggleDefinitionList(editor); } else if (type === "quote") { @@ -66,12 +68,21 @@ export const ToolbarBlockOptions = ({ options }: ToolbarCategoryProps if (!visibleOptions.length) return null; return ( - + {visibleOptions.map((type) => ( - - onClick(type.value)} /> - + { + e.preventDefault(); + onClick(type.value); + }} + onMouseDown={(e) => e.preventDefault()} + onMouseUp={(e) => e.preventDefault()} + value={type.value} + disabled={type.disabled} + type={type.value} + /> ))} - + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarInlineOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarInlineOptions.tsx index eabcc5f647..11b2071532 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarInlineOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarInlineOptions.tsx @@ -7,12 +7,11 @@ */ import { useCallback } from "react"; -import { Editor, Element } from "slate"; -import { useSlate, useSlateSelector } from "slate-react"; -import { ToggleItem } from "@radix-ui/react-toolbar"; -import { StyledToggleGroup, ToolbarCategoryProps } from "./SlateToolbar"; -import ToolbarButton from "./ToolbarButton"; +import { Editor, Element, Transforms } from "slate"; +import { ReactEditor, useSlate, useSlateSelection, useSlateSelector } from "slate-react"; +import { ToolbarCategoryProps } from "./SlateToolbar"; import { InlineType } from "./toolbarState"; +import { ToolbarToggleButton, ToolbarToggleGroupRoot } from "./ToolbarToggle"; import { insertComment } from "../comment/inline/utils"; import { insertInlineConcept } from "../concept/inline/utils"; import { insertLink } from "../link/utils"; @@ -38,9 +37,13 @@ const getCurrentInlineValues = (editor: Editor): InlineType | undefined => { export const ToolbarInlineOptions = ({ options }: ToolbarCategoryProps) => { const editor = useSlate(); const value = useSlateSelector(getCurrentInlineValues); + const selection = useSlateSelection(); const onClick = useCallback( (type: InlineType) => { + if (!selection) return; + Transforms.select(editor, selection); + ReactEditor.focus(editor); if (type === "content-link") { insertLink(editor); } @@ -57,19 +60,27 @@ export const ToolbarInlineOptions = ({ options }: ToolbarCategoryProps !option.hidden); if (!visibleOptions.length) return null; return ( - + {visibleOptions.map((type) => ( - - onClick(type.value)} disabled={type.disabled} /> - + { + e.preventDefault(); + onClick(type.value); + }} + onMouseDown={(e) => e.preventDefault()} + disabled={type.disabled} + key={type.value} + value={type.value} + /> ))} - + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx index f32620d797..77ee313756 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx @@ -6,20 +6,27 @@ * */ -import { useCallback } from "react"; +import { useCallback, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Editor, Element, Transforms } from "slate"; -import { ReactEditor, useSlate, useSlateSelector } from "slate-react"; -import { ToolbarButton } from "@radix-ui/react-toolbar"; -import { DropdownItem, DropdownMenu, DropdownTrigger } from "@ndla/dropdown-menu"; -import { ArrowDropDown } from "@ndla/icons/common"; +import { ReactEditor, useSlate, useSlateSelection, useSlateSelector } from "slate-react"; +import { createListCollection } from "@ark-ui/react"; +import { Language } from "@ndla/icons/common"; +import { SelectContent, SelectRoot, SelectPositioner, SelectValueText, SelectLabel } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { ToolbarCategoryProps } from "./SlateToolbar"; -import UIToolbarButton from "./ToolbarButton"; -import { ToolbarDropdownButton, ToolbarDropdownContent } from "./toolbarDropdownComponents"; import { LanguageType } from "./toolbarState"; +import { getTitle } from "./ToolbarToggle"; +import { GenericSelectItem, GenericSelectTrigger } from "../../../abstractions/Select"; import hasNodeOfType from "../../utils/hasNodeOfType"; import { defaultSpanBlock } from "../span/utils"; +const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { + base: { + width: "surface.xxsmall", + }, +}); + const getCurrentLanguage = (editor: Editor) => { const [currentBlock] = Editor.nodes(editor, { @@ -32,14 +39,15 @@ const getCurrentLanguage = (editor: Editor) => { }; export const ToolbarLanguageOptions = ({ options }: ToolbarCategoryProps) => { - const { t } = useTranslation(); + const { t, i18n } = useTranslation(); const editor = useSlate(); const currentLanguage = useSlateSelector(getCurrentLanguage); + const selection = useSlateSelection(); const onClick = useCallback( (language: string) => { - const sel = editor.selection; - Transforms.select(editor, sel!); + if (!selection) return; + Transforms.select(editor, selection); ReactEditor.focus(editor); const wrappedInSpan = hasNodeOfType(editor, "span"); if (wrappedInSpan && language === "none") { @@ -50,73 +58,59 @@ export const ToolbarLanguageOptions = ({ options }: ToolbarCategoryProps Element.isElement(n) && n.type === "span", - }); - Transforms.wrapNodes(editor, defaultSpanBlock({ lang: language }), { - at: Editor.unhangRange(editor, editor.selection!), - split: true, - }); + Transforms.setNodes( + editor, + { data: { lang: language } }, + { match: (n) => Element.isElement(n) && n.type === "span" }, + ); } }, - [editor], + [editor, selection], ); - const onCloseFocus = useCallback( - (e: Event) => { - e.preventDefault(); - const sel = editor.selection; - if (!sel) return; - setTimeout(() => { - Transforms.select(editor, sel); - ReactEditor.focus(editor); - }, 0); - }, - [editor], - ); + const title = useMemo(() => getTitle(i18n, t, "language", false, false), [i18n, t]); + + const collection = useMemo(() => { + const visibleOptions = options.filter((option) => !option.hidden); + if (!visibleOptions.length) return undefined; + return createListCollection({ + items: [{ value: "none" }].concat(visibleOptions), + itemToString: (item) => t(`languages.${item.value}`), + itemToValue: (item) => item.value, + }); + }, [options, t]); - const visibleOptions = options.filter((option) => !option.hidden); - if (!visibleOptions.length) return null; + if (!collection) return null; return ( - - - - - {currentLanguage ? t(`languages.${currentLanguage}`) : t("editorToolbar.noneLanguage")} - - - - - - - onClick("none")} - > - {t("editorToolbar.noneLanguage")} - - - {visibleOptions.map((option) => ( - - onClick(details.value[0])} + > + {title} + + + + + + + {collection.items.map((option) => ( + onClick(option.value)} + item={{ label: option.value, value: option.value }} > {t(`languages.${option.value}`)} - - - ))} - - + + ))} + + + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarMarkOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarMarkOptions.tsx index d615beeb89..e60089e997 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarMarkOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarMarkOptions.tsx @@ -9,10 +9,9 @@ import isEqual from "lodash/isEqual"; import { Editor } from "slate"; import { useSlate, useSlateSelector } from "slate-react"; -import { ToggleItem } from "@radix-ui/react-toolbar"; -import { StyledToggleGroup, ToolbarCategoryProps } from "./SlateToolbar"; -import ToolbarButton from "./ToolbarButton"; +import { ToolbarCategoryProps } from "./SlateToolbar"; import { MarkType } from "./toolbarState"; +import { ToolbarToggleButton, ToolbarToggleGroupRoot } from "./ToolbarToggle"; import { toggleMark } from "../mark/utils"; const getMarks = (editor: Editor) => { @@ -30,12 +29,20 @@ export const ToolbarMarkOptions = ({ options }: ToolbarCategoryProps) const visibleOptions = options.filter((option) => !option.hidden); if (!visibleOptions.length) return null; return ( - + {visibleOptions.map((type) => ( - - toggleMark(e, editor, type.value)} type={type.value} /> - + { + e.preventDefault(); + toggleMark(e, editor, type.value); + }} + onMouseDown={(e) => e.preventDefault()} + type={type.value} + key={type.value} + value={type.value} + disabled={type.disabled} + /> ))} - + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarTableOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarTableOptions.tsx index 8fc2fbc7e1..b2511353e7 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarTableOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarTableOptions.tsx @@ -8,11 +8,10 @@ import { Editor, Element } from "slate"; import { useSlate, useSlateSelector } from "slate-react"; -import { ToggleItem } from "@radix-ui/react-toolbar"; import { handleClickTable } from "./handleMenuClicks"; -import { StyledToggleGroup, ToolbarCategoryProps } from "./SlateToolbar"; -import ToolbarButton from "./ToolbarButton"; +import { ToolbarCategoryProps } from "./SlateToolbar"; import { TableType } from "./toolbarState"; +import { ToolbarToggleButton, ToolbarToggleGroupRoot } from "./ToolbarToggle"; const getCurrentBlockValues = (editor: Editor) => { const [currentTableCell] = @@ -35,12 +34,20 @@ export const ToolbarTableOptions = ({ options }: ToolbarCategoryProps if (!visibleOptions.length) return null; return ( - + {visibleOptions.map((type) => ( - - handleClickTable(e, editor, type.value)} /> - + { + e.preventDefault(); + handleClickTable(e, editor, type.value); + }} + onMouseDown={(e) => e.preventDefault()} + key={type.value} + value={type.value} + disabled={type.disabled} + /> ))} - + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx index d95f16fcc4..2472c8b5e1 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx @@ -6,18 +6,41 @@ * */ -import { useCallback } from "react"; +import { useCallback, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Element, Editor, Transforms } from "slate"; -import { ReactEditor, useSlate, useSlateSelector } from "slate-react"; -import { ToolbarButton } from "@radix-ui/react-toolbar"; -import { DropdownItem, DropdownMenu, DropdownTrigger } from "@ndla/dropdown-menu"; -import { ArrowDropDown } from "@ndla/icons/common"; +import { ReactEditor, useSlate, useSlateSelection, useSlateSelector } from "slate-react"; +import { createListCollection } from "@ark-ui/react"; +import { + SelectContent, + SelectItem, + SelectItemText, + SelectLabel, + SelectPositioner, + SelectRoot, + SelectValueText, +} from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { handleTextChange } from "./handleMenuClicks"; import { ToolbarCategoryProps } from "./SlateToolbar"; -import UIToolbarButton from "./ToolbarButton"; -import { ToolbarDropdownButton, ToolbarDropdownContent } from "./toolbarDropdownComponents"; import { TextType } from "./toolbarState"; +import { getTitle, iconMapping } from "./ToolbarToggle"; +import { GenericSelectItemIndicator, GenericSelectTrigger } from "../../../abstractions/Select"; + +const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { + base: { + width: "surface.xxsmall", + justifyContent: "space-between", + }, +}); + +const TextWrapper = styled("div", { + base: { + display: "flex", + alignItems: "baseline", + gap: "3xsmall", + }, +}); const getTextValue = (editor: Editor): TextType => { const [match] = editor.selection @@ -35,58 +58,64 @@ const getTextValue = (editor: Editor): TextType => { }; export const ToolbarTextOptions = ({ options }: ToolbarCategoryProps) => { - const { t } = useTranslation(); + const { t, i18n } = useTranslation(); const editor = useSlate(); + const selection = useSlateSelection(); const type = useSlateSelector(getTextValue); const onTextOptionClick = useCallback( (value: string) => { + if (!selection) return; + Transforms.select(editor, selection); + ReactEditor.focus(editor); handleTextChange(editor, value); }, - [editor], + [editor, selection], ); - const onCloseFocus = useCallback( - (e: Event) => { - e.preventDefault(); - const sel = editor.selection; - if (!sel) return; - // Not having this timeout will cause the toolbar to close. - setTimeout(() => { - Transforms.select(editor, sel); - ReactEditor.focus(editor); - }, 10); - }, - [editor], - ); + const collection = useMemo(() => { + const visibleOptions = options.filter((option) => !option.hidden); + if (!visibleOptions.length) return undefined; + return createListCollection({ + items: visibleOptions, + itemToValue: (item) => item.value, + itemToString: (item) => t(`editorToolbar.${item.value}-value`), + }); + }, [options, t]); + + const title = useMemo(() => getTitle(i18n, t, type, false, false), [i18n, t, type]); + const TriggerIcon = useMemo(() => (type ? iconMapping[type] : undefined), [type]); - const visibleOptions = options.filter((option) => !option.hidden); - if (!visibleOptions.length) return null; + if (!collection) return null; return ( - - - - - {t(`editorToolbar.${type}-value`)} - - - - - - {visibleOptions.map((option) => ( - onTextOptionClick(option.value)} - > - - {t(`editorToolbar.${option.value}-value`)} - - - ))} - - + onTextOptionClick(details.value[0])} + > + {title} + + {TriggerIcon && } + + + + + {collection.items.map((item) => { + const Icon = item.value ? iconMapping[item.value] : undefined; + return ( + + + {Icon && } + {t(`editorToolbar.${item.value}-value`)} + + + + ); + })} + + + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarButton.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx similarity index 60% rename from src/components/SlateEditor/plugins/toolbar/ToolbarButton.tsx rename to src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx index 6ea2941af6..d535f84378 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarButton.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx @@ -9,9 +9,7 @@ import { TFunction } from "i18next"; import { ElementType, ReactNode, forwardRef, useMemo } from "react"; import { CustomI18n, useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { ButtonProps, ButtonV2 } from "@ndla/button"; -import { colors, fonts, spacing } from "@ndla/core"; +import { ToggleGroupItemProps } from "@ark-ui/react"; import { Language, Comment } from "@ndla/icons/common"; import { Bold, @@ -33,37 +31,45 @@ import { FormatList, Globe, } from "@ndla/icons/editor"; +import { Text, ToggleGroupItem, ToggleGroupRoot } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; +import { FontWeightToken } from "@ndla/styled-system/tokens"; -const StyledHeadingSpan = styled.span` - text-align: center; - width: ${spacing.normal}; - ${fonts.sizes("14px", "14px")}; -`; - -interface HeadingSpanProps { +interface HeadingProps { title: string; + fontWeight?: FontWeightToken; +} + +interface HeadingSpanProps extends HeadingProps { children: ReactNode; } -const HeadingSpan = ({ title, children }: HeadingSpanProps) => { - return {children}; +const StyledText = styled(Text, { + base: { + width: "medium", + height: "medium", + }, +}); + +const HeadingSpan = ({ children, ...rest }: HeadingSpanProps) => { + return ( + + {children} + + ); }; -interface HeadingProps { - title: string; -} - -const Paragraph = ({ title }: HeadingProps) => P; -const HeadingOne = ({ title }: HeadingProps) => H1; -const HeadingTwo = ({ title }: HeadingProps) => H2; -const HeadingThree = ({ title }: HeadingProps) => H3; -const HeadingFour = ({ title }: HeadingProps) => H4; +const Paragraph = (props: HeadingProps) => P; +const HeadingOne = (props: HeadingProps) => H1; +const HeadingTwo = (props: HeadingProps) => H2; +const HeadingThree = (props: HeadingProps) => H3; +const HeadingFour = (props: HeadingProps) => H4; // Fetched from https://github.com/ianstormtaylor/is-hotkey/blob/master/src/index.js export const IS_MAC = typeof window != "undefined" && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform); const options = { ctrl: IS_MAC ? "cmd" : "ctrl" }; -const icon: Record = { +export const iconMapping: Record = { bold: Bold, italic: Italic, underlined: Underline, @@ -98,19 +104,7 @@ interface Props { disabled?: boolean; } -const StyledButton = styled(ButtonV2)` - color: ${colors.brand.greyDark}; - display: inline-flex; - align-items: center; - &[data-state="on"] { - background-color: ${colors.brand.light}; - &:hover { - color: ${colors.brand.greyDark}; - } - } -`; - -const getTitle = ( +export const getTitle = ( i18n: CustomI18n, t: TFunction, type?: string, @@ -129,28 +123,33 @@ const getTitle = ( return t(`editorToolbar.${type}`, options); }; -const ToolbarButton = forwardRef & Props>( - ({ type, children, noTitle, disabled, ...rest }, ref) => { - const Icon = useMemo(() => (type ? icon[type] : undefined), [type]); +export const ToolbarToggleButton = forwardRef & Props>( + ({ type, children, noTitle, disabled, value, ...rest }, ref) => { + const Icon = useMemo(() => (type ? iconMapping[type] : undefined), [type]); const { i18n, t } = useTranslation(); const title = useMemo(() => getTitle(i18n, t, type, noTitle, disabled), [i18n, t, type, noTitle, disabled]); return ( - {Icon && } {children} - + ); }, ); -export default ToolbarButton; +export const ToolbarToggleGroupRoot = styled(ToggleGroupRoot, { + base: { + gap: "3xsmall", + }, +}); diff --git a/src/components/SlateEditor/plugins/toolbar/handleMenuClicks.ts b/src/components/SlateEditor/plugins/toolbar/handleMenuClicks.ts index 2f534a9db4..53dbc98fdd 100644 --- a/src/components/SlateEditor/plugins/toolbar/handleMenuClicks.ts +++ b/src/components/SlateEditor/plugins/toolbar/handleMenuClicks.ts @@ -7,7 +7,7 @@ */ import { SyntheticEvent } from "react"; -import { Editor, Transforms, Element, Range, Path, Node, BaseRange } from "slate"; +import { Editor, Transforms, Element, Range, Node, BaseRange } from "slate"; import { jsx as slatejsx } from "slate-hyperscript"; import { BlockType, InlineType, TextType, getEditorAncestors } from "./toolbarState"; import toggleBlock from "../../utils/toggleBlock"; diff --git a/src/components/SlateEditor/plugins/toolbar/toolbarDropdownComponents.tsx b/src/components/SlateEditor/plugins/toolbar/toolbarDropdownComponents.tsx deleted file mode 100644 index d678c8d64b..0000000000 --- a/src/components/SlateEditor/plugins/toolbar/toolbarDropdownComponents.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2024-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import styled from "@emotion/styled"; -import { spacing, colors } from "@ndla/core"; -import { DropdownContent } from "@ndla/dropdown-menu"; -import ToolbarButton from "./ToolbarButton"; - -export const ToolbarDropdownContent = styled(DropdownContent)` - padding: ${spacing.xsmall}; - flex: 1; - align-items: flex-start; - border: 1px solid ${colors.brand.tertiary}; - max-height: 50dvh; - overflow-y: scroll; -`; - -export const ToolbarDropdownButton = styled(ToolbarButton)` - display: flex; - flex: 1; - width: 100%; - justify-content: flex-start; -`; diff --git a/src/phrases/phrases-en.ts b/src/phrases/phrases-en.ts index 73d1f8e7c1..1edb3c8783 100644 --- a/src/phrases/phrases-en.ts +++ b/src/phrases/phrases-en.ts @@ -113,6 +113,7 @@ const phrases = { pli: "Pali", empty: "No languages left", change: "Change to {{language}} version", + none: "None", }, welcomePage: { lastFavorited: "Last favorited resource: ", diff --git a/src/phrases/phrases-nb.ts b/src/phrases/phrases-nb.ts index 1eb272969e..81a1147300 100644 --- a/src/phrases/phrases-nb.ts +++ b/src/phrases/phrases-nb.ts @@ -113,6 +113,7 @@ const phrases = { pli: "Pali", empty: "Ingen flere språk", change: "Bytt til {{language}} versjon", + none: "Ingen", }, welcomePage: { lastFavorited: "Siste hjertemarkerte ressurs: ", diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 4867dcf700..0aed726c76 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -113,6 +113,7 @@ const phrases = { pli: "Pali", empty: "Ingen fleire språk", change: "Bytt til {{language}} versjon", + none: "Ingen", }, welcomePage: { lastFavorited: "Siste hjertemarkerte ressurs: ", From e36caae0b68b16787ef08bf27f34a0ac7ad78da3 Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Fri, 15 Nov 2024 10:36:31 +0100 Subject: [PATCH 002/170] refactor: use primitives Button in TaxonomyBlockNode --- src/components/Taxonomy/TaxonomyBlockNode.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Taxonomy/TaxonomyBlockNode.tsx b/src/components/Taxonomy/TaxonomyBlockNode.tsx index d82ee77da7..8d317015df 100644 --- a/src/components/Taxonomy/TaxonomyBlockNode.tsx +++ b/src/components/Taxonomy/TaxonomyBlockNode.tsx @@ -9,9 +9,9 @@ import { useCallback, useMemo } from "react"; import { useTranslation } from "react-i18next"; import styled from "@emotion/styled"; -import { ButtonV2 } from "@ndla/button"; import { colors, fonts, spacing } from "@ndla/core"; import { CheckboxCircleFill } from "@ndla/icons/editor"; +import { Button } from "@ndla/primitives"; import { Node, NodeChild } from "@ndla/types-taxonomy"; import Fade from "./Fade"; import { ItemTitleButton, StructureWrapper, StyledItemBar, StyledStructureItem } from "./nodeStyles"; @@ -86,7 +86,7 @@ export const TaxonomyBlockNode = ({ {t("taxonomy.topics.addedTopic")} ) : onRootSelected ? ( - onRootSelected(node)}> + onRootSelected(node)}> {t("taxonomy.topics.filestructureButton")} ) : null} @@ -133,7 +133,7 @@ const StyledChecked = styled.div` } `; -const StyledButton = styled(ButtonV2)` +const StyledButton = styled(Button)` opacity: 0; `; @@ -168,7 +168,7 @@ const ChildNode = ({ node, onSelect, toggleOpen, openedPaths, parentActive, sele {t("taxonomy.topics.addedTopic")} ) : ( - + {t("taxonomy.topics.filestructureButton")} )} From 36d9c3bf7a10720f66c7f422da3687ea8a46660a Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Mon, 18 Nov 2024 10:07:03 +0100 Subject: [PATCH 003/170] Fix topic article route in structure edit --- .../StructurePage/resourceComponents/TopicResourceBanner.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx b/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx index 3d5fae2c41..6ab3688edf 100644 --- a/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx +++ b/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx @@ -145,7 +145,7 @@ const TopicResourceBanner = ({ topicNodes, showQuality, }: Props) => { - const { t } = useTranslation(); + const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); const elementCount = Object.values(contentMeta).length; @@ -192,7 +192,7 @@ const TopicResourceBanner = ({ {numericId ? ( Date: Mon, 11 Nov 2024 13:38:33 +0100 Subject: [PATCH 004/170] Refactor + simplify article composition with comments --- src/components/Accordion/FormAccordions.tsx | 16 -- .../Accordion/FormAccordionsWithComments.tsx | 173 ------------ src/components/Accordion/OpenAllButton.tsx | 55 ---- src/components/Footer/Footer.tsx | 5 +- src/components/FormWrapper.tsx | 12 +- .../SimpleLanguageHeader.tsx | 4 +- src/components/ResourcePage.tsx | 9 +- src/components/StyledFormComponents.tsx | 23 -- src/constants.ts | 2 +- .../components/FrontpageArticleForm.tsx | 6 +- .../components/FrontpageArticlePanels.tsx | 172 +++++++----- .../components/LearningResourceForm.tsx | 7 +- .../components/LearningResourcePanels.tsx | 250 +++++++++++------- .../TopicArticleAccordionPanels.tsx | 207 +++++++++------ .../components/TopicArticleForm.tsx | 7 +- .../ArticlePage/components/CommentSection.tsx | 6 +- src/containers/ArticlePage/styles.ts | 15 -- .../AudioUploader/components/AudioForm.tsx | 18 +- .../components/SubjectpageForm.tsx | 20 +- .../NdlaFilm/components/NdlaFilmForm.tsx | 18 +- .../PreviewDraftPage/LanguageSelector.tsx | 6 - 21 files changed, 428 insertions(+), 603 deletions(-) delete mode 100644 src/components/Accordion/FormAccordionsWithComments.tsx delete mode 100644 src/components/Accordion/OpenAllButton.tsx delete mode 100644 src/components/StyledFormComponents.tsx delete mode 100644 src/containers/ArticlePage/styles.ts diff --git a/src/components/Accordion/FormAccordions.tsx b/src/components/Accordion/FormAccordions.tsx index 9a0b77c164..4c98acbcb3 100644 --- a/src/components/Accordion/FormAccordions.tsx +++ b/src/components/Accordion/FormAccordions.tsx @@ -10,7 +10,6 @@ import { ReactElement, memo, useState } from "react"; import { AccordionRoot } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { FormAccordionProps } from "./FormAccordion"; -import OpenAllButton from "./OpenAllButton"; type ChildType = ReactElement | undefined | false; @@ -29,14 +28,6 @@ const AccordionsWrapper = styled("div", { }, }); -const FlexWrapper = styled("div", { - base: { - display: "flex", - flexDirection: "row", - justifyContent: "flex-end", - }, -}); - const StyledAccordionRoot = styled(AccordionRoot, { base: { width: "100%", @@ -48,13 +39,6 @@ const FormAccordions = ({ defaultOpen, children }: Props) => { return ( - - - | undefined | false; - -interface Props { - defaultOpen: string[]; - children: ChildType | ChildType[]; - article?: IArticle; - taxonomy?: Node[]; - updateNotes?: (art: IUpdatedArticle) => Promise; -} - -const ContentWrapper = styled.div` - display: flex; - flex-direction: column; - gap: ${spacing.small}; -`; - -const FlexWrapper = styled.div` - display: flex; -`; - -const RightFlexWrapper = styled.div` - display: flex; - gap: ${spacing.small}; -`; - -const CommentWrapper = styled.div` - width: 100%; - max-width: ${COMMENT_WIDTH}px; - margin-left: ${SPACING_COMMENT}px; - display: flex; - flex-direction: column; - &[data-hidden="true"] { - visibility: none; - } - &[data-none="true"] { - display: none; - } -`; - -const StyledSwitchRoot = styled(SwitchRoot)` - min-height: 40px; -`; - -const FormControls = styled.div` - display: flex; - width: 100%; - padding-left: ${spacing.small}; - justify-content: flex-end; - &[data-enabled-quality-evaluation="true"] { - justify-content: space-between; - } -`; - -const StyledAccordionRoot = styled(AccordionRoot)` - width: 100%; -`; - -const FormAccordionsWithComments = ({ defaultOpen, children, article, taxonomy, updateNotes }: Props) => { - const { t } = useTranslation(); - const { toggleWideArticles, isWideArticle } = useWideArticle(); - const [revisionMetaField, , revisionMetaHelpers] = useField("revisionMeta"); - - const [openAccordions, setOpenAccordions] = useState(defaultOpen); - const [hideComments, setHideComments] = useLocalStorageBooleanState(STORED_HIDE_COMMENTS); - - const isTopicArticle = article?.articleType === "topic-article"; - const isFrontPageArticle = article?.articleType === "frontpage-article"; - - const disableComments = useMemo( - () => !isTopicArticle && [PUBLISHED, ARCHIVED, UNPUBLISHED].some((s) => s === article?.status.current), - [article?.status, isTopicArticle], - ); - - // Topics are updated from structure edit page - const withoutTopics = taxonomy?.filter((n) => n.nodeType !== "TOPIC"); - - return ( - - - - {!isTopicArticle && !isFrontPageArticle && ( - - )} - - {!!article?.id && isFrontPageArticle && ( - toggleWideArticles(article.id)}> - {t("frontpageArticleForm.isFrontpageArticle.toggleArticle")} - - - - - - )} - - - - - {!disableComments && ( - setHideComments(!hideComments)}> - {t("form.comment.showComments")} - - - - - - )} - - - - setOpenAccordions(details.value)} - lazyMount - unmountOnExit - > - {children} - - - {!hideComments && !disableComments && } - - - - ); -}; - -export default memo(FormAccordionsWithComments); diff --git a/src/components/Accordion/OpenAllButton.tsx b/src/components/Accordion/OpenAllButton.tsx deleted file mode 100644 index ae171848f3..0000000000 --- a/src/components/Accordion/OpenAllButton.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2024-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { Children, useCallback, useMemo } from "react"; -import { useTranslation } from "react-i18next"; -import { Button } from "@ndla/primitives"; -import { styled } from "@ndla/styled-system/jsx"; -import { ChildType } from "./FormAccordionsWithComments"; - -interface Props { - openAccordions: string[]; - setOpenAccordions: (values: string[]) => void; - formAccordionChildren: ChildType | ChildType[]; -} - -const StyledButton = styled(Button, { - base: { - alignSelf: "flex-end", - }, -}); - -const OpenAllButton = ({ openAccordions, setOpenAccordions, formAccordionChildren }: Props) => { - const { t } = useTranslation(); - - const accordionChildren = useMemo( - () => Children.map(formAccordionChildren, (c) => (c ? c.props?.id : false))?.filter(Boolean) ?? [], - [formAccordionChildren], - ); - - const allOpen = useMemo( - () => accordionChildren.length === openAccordions.length, - [accordionChildren.length, openAccordions.length], - ); - - const onChangeAll = useCallback(() => { - if (allOpen) { - setOpenAccordions([]); - } else { - setOpenAccordions(accordionChildren); - } - }, [allOpen, setOpenAccordions, accordionChildren]); - - return ( - - {allOpen ? t("accordion.closeAll") : t("accordion.openAll")} - - ); -}; - -export default OpenAllButton; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 3ef2cb07b5..5c37110312 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -9,8 +9,7 @@ import { ReactNode } from "react"; import styled from "@emotion/styled"; import { colors, spacing, stackOrder } from "@ndla/core"; -import { MAX_PAGE_WIDTH } from "../../constants"; -import { MAX_WIDTH_WITH_COMMENTS } from "../../containers/ArticlePage/styles"; +import { MAX_PAGE_WIDTH, MAX_PAGE_WIDTH_WITH_COMMENTS } from "../../constants"; const StyledFooter = styled.footer` position: fixed; @@ -32,7 +31,7 @@ const StyledContentWrapper = styled.div` justify-content: space-between; gap: ${spacing.medium}; &[data-article="true"] { - max-width: ${MAX_WIDTH_WITH_COMMENTS}px; + max-width: ${MAX_PAGE_WIDTH_WITH_COMMENTS}px; } > div { display: flex; diff --git a/src/components/FormWrapper.tsx b/src/components/FormWrapper.tsx index f30c59dcc0..098be899b5 100644 --- a/src/components/FormWrapper.tsx +++ b/src/components/FormWrapper.tsx @@ -6,20 +6,24 @@ * */ -import { Form } from "formik"; import { ReactNode } from "react"; -import StyledForm from "./StyledFormComponents"; +import { styled } from "@ndla/styled-system/jsx"; +import { Form } from "./FormikForm"; interface Props { inModal?: boolean; children: ReactNode; } -const DivForm = StyledForm.withComponent("div"); +const StyledForm = styled(Form, { + base: { + width: "100%", + }, +}); const FormWrapper = ({ inModal, children }: Props) => { if (inModal) { - return {children}; + return {children}; } return
{children}
; }; diff --git a/src/components/HeaderWithLanguage/SimpleLanguageHeader.tsx b/src/components/HeaderWithLanguage/SimpleLanguageHeader.tsx index c92d3372ed..6cd0ef8862 100644 --- a/src/components/HeaderWithLanguage/SimpleLanguageHeader.tsx +++ b/src/components/HeaderWithLanguage/SimpleLanguageHeader.tsx @@ -52,7 +52,7 @@ const SimpleLanguageHeader = ({ ); return ( - <> +
)} - +
); }; diff --git a/src/components/ResourcePage.tsx b/src/components/ResourcePage.tsx index 983b910f7a..01ae32dd14 100644 --- a/src/components/ResourcePage.tsx +++ b/src/components/ResourcePage.tsx @@ -16,9 +16,8 @@ import { HelmetWithTracker } from "@ndla/tracker"; import { NynorskTranslateProvider } from "./NynorskTranslateProvider"; import Spinner from "./Spinner"; import { useWideArticle } from "./WideArticleEditorProvider"; -import { MAX_PAGE_WIDTH } from "../constants"; +import { MAX_PAGE_WIDTH, MAX_PAGE_WIDTH_WITH_COMMENTS } from "../constants"; import Footer from "../containers/App/components/FooterWrapper"; -import { MAX_WIDTH_FRONTPAGE_WITH_COMMENTS, MAX_WIDTH_WITH_COMMENTS } from "../containers/ArticlePage/styles"; import NotFoundPage from "../containers/NotFoundPage/NotFoundPage"; import { usePreviousLocation } from "../util/routeHelpers"; @@ -36,12 +35,8 @@ const PageContent = styled.div` padding-right: 24px; } max-width: ${MAX_PAGE_WIDTH}px; - - &[data-wide="true"] { - max-width: ${MAX_WIDTH_FRONTPAGE_WITH_COMMENTS}px; - } &[data-article="true"] { - max-width: ${MAX_WIDTH_WITH_COMMENTS}px; + max-width: ${MAX_PAGE_WIDTH_WITH_COMMENTS}px; } `; diff --git a/src/components/StyledFormComponents.tsx b/src/components/StyledFormComponents.tsx deleted file mode 100644 index e5af7e9544..0000000000 --- a/src/components/StyledFormComponents.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2022-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { Form } from "formik"; -import styled from "@emotion/styled"; -import { spacing, mq } from "@ndla/core"; - -const StyledForm = styled(Form)` - width: 100%; - margin-top: ${spacing.normal}; - ${mq.range({ from: "37.5em" })} { - padding-left: 0; - padding-right: 0; - padding-top: 0; - } -`; - -export default StyledForm; diff --git a/src/constants.ts b/src/constants.ts index 385f96665c..578d6e650d 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -76,7 +76,7 @@ export const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024 * 40; // 40MB. export const LAST_UPDATED_SIZE = 50; export const MAX_PAGE_WIDTH = 1024; -export const MAX_FRONTPAGE_ARTICLE_WIDTH = 1400; +export const MAX_PAGE_WIDTH_WITH_COMMENTS = 1256; export const LOCALE_VALUES = ["nb", "nn", "en", "se", "sma"] as const; diff --git a/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticleForm.tsx b/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticleForm.tsx index 78d2bcd969..320cfd96d7 100644 --- a/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticleForm.tsx +++ b/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticleForm.tsx @@ -12,10 +12,10 @@ import { useTranslation } from "react-i18next"; import { UseQueryResult } from "@tanstack/react-query"; import { IArticle, IUpdatedArticle, IStatus } from "@ndla/types-backend/draft-api"; import FrontpageArticlePanels from "./FrontpageArticlePanels"; +import { Form } from "../../../../components/FormikForm"; import validateFormik, { getWarnings } from "../../../../components/formikValidationSchema"; import HeaderWithLanguage from "../../../../components/HeaderWithLanguage"; import EditorFooter from "../../../../components/SlateEditor/EditorFooter"; -import StyledForm from "../../../../components/StyledFormComponents"; import { validateDraft } from "../../../../modules/draft/draftApi"; import { useLicenses, useDraftStatusStateMachine } from "../../../../modules/draft/draftQueries"; import { frontPageArticleRules, isFormikFormDirty } from "../../../../util/formHelper"; @@ -79,7 +79,7 @@ const FrontpageArticleForm = ({ validate={(values) => validateFormik(values, frontPageArticleRules, t)} initialStatus={{ warnings: initialWarnings }} > - +
- + ); }; diff --git a/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticlePanels.tsx b/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticlePanels.tsx index b0711081c1..fd95fa5a1d 100644 --- a/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticlePanels.tsx +++ b/src/containers/ArticlePage/FrontpageArticlePage/components/FrontpageArticlePanels.tsx @@ -9,18 +9,37 @@ import { useFormikContext } from "formik"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { PageContent } from "@ndla/primitives"; +import { PageContent, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { IArticle } from "@ndla/types-backend/draft-api"; import FrontpageArticleFormContent from "./FrontpageArticleFormContent"; import FormAccordion from "../../../../components/Accordion/FormAccordion"; -import FormAccordionsWithComments from "../../../../components/Accordion/FormAccordionsWithComments"; +import FormAccordions from "../../../../components/Accordion/FormAccordions"; import { useWideArticle } from "../../../../components/WideArticleEditorProvider"; +import { STORED_HIDE_COMMENTS } from "../../../../constants"; import { CopyrightFieldGroup, VersionAndNotesPanel, MetaDataField } from "../../../FormikForm"; import { FrontpageArticleFormType } from "../../../FormikForm/articleFormHooks"; +import { useLocalStorageBooleanState } from "../../../WelcomePage/hooks/storedFilterHooks"; +import CommentSection, { RESET_COMMENTS_STATUSES } from "../../components/CommentSection"; import PanelTitleWithChangeIndicator from "../../components/PanelTitleWithChangeIndicator"; import RevisionNotes from "../../components/RevisionNotes"; import { FlatArticleKeys } from "../../components/types"; +const StyledWrapper = styled("div", { + base: { + display: "grid", + gridTemplateColumns: "1fr auto", + }, +}); + +const StyledControls = styled("div", { + base: { + display: "flex", + gap: "small", + justifyContent: "flex-end", + }, +}); + interface Props { article?: IArticle; articleHistory: IArticle[] | undefined; @@ -28,9 +47,10 @@ interface Props { } const FrontpageArticlePanels = ({ article, articleHistory, articleLanguage }: Props) => { + const [hideComments, setHideComments] = useLocalStorageBooleanState(STORED_HIDE_COMMENTS); const { t } = useTranslation(); const { errors } = useFormikContext(); - const { isWideArticle } = useWideArticle(); + const { toggleWideArticles, isWideArticle } = useWideArticle(); const contentTitleFields = useMemo( () => ["title.title", "introduction.introduction", "content.content"], @@ -38,63 +58,97 @@ const FrontpageArticlePanels = ({ article, articleHistory, articleLanguage }: Pr ); const copyrightFields = useMemo(() => ["copyright"], []); + const removeComments = useMemo( + () => RESET_COMMENTS_STATUSES.some((s) => s === article?.status.current), + [article?.status], + ); + return ( - - - } - hasError={!!(errors.title || errors.introduction || errors.content)} - > - - - - - - } - hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} - > - - - - - - - - - {article && ( - - - - )} - + <> + + {!!article?.id && ( + toggleWideArticles(article.id)}> + {t("frontpageArticleForm.isFrontpageArticle.toggleArticle")} + + + + + + )} + {!removeComments && ( + setHideComments(!hideComments)}> + {t("form.comment.showComments")} + + + + + + )} + + + + + } + hasError={!!(errors.title || errors.introduction || errors.content)} + > + + + + + + } + hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} + > + + + + + + + + + {article && ( + + + + )} + + {!hideComments && !removeComments && } + + ); }; diff --git a/src/containers/ArticlePage/LearningResourcePage/components/LearningResourceForm.tsx b/src/containers/ArticlePage/LearningResourcePage/components/LearningResourceForm.tsx index 1d999872af..5b5c7879d7 100644 --- a/src/containers/ArticlePage/LearningResourcePage/components/LearningResourceForm.tsx +++ b/src/containers/ArticlePage/LearningResourcePage/components/LearningResourceForm.tsx @@ -15,11 +15,10 @@ import { IArticle, IUpdatedArticle, IStatus } from "@ndla/types-backend/draft-ap import { Node } from "@ndla/types-taxonomy"; import LearningResourcePanels from "./LearningResourcePanels"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import { FormActionsContainer } from "../../../../components/FormikForm"; +import { Form, FormActionsContainer } from "../../../../components/FormikForm"; import validateFormik, { getWarnings } from "../../../../components/formikValidationSchema"; import HeaderWithLanguage from "../../../../components/HeaderWithLanguage"; import EditorFooter from "../../../../components/SlateEditor/EditorFooter"; -import StyledForm from "../../../../components/StyledFormComponents"; import { ARCHIVED, UNPUBLISHED } from "../../../../constants"; import { validateDraft } from "../../../../modules/draft/draftApi"; import { useLicenses, useDraftStatusStateMachine } from "../../../../modules/draft/draftQueries"; @@ -123,7 +122,7 @@ const LearningResourceForm = ({ validate={validate} initialStatus={initialWarnings} > - +
- + ); }; diff --git a/src/containers/ArticlePage/LearningResourcePage/components/LearningResourcePanels.tsx b/src/containers/ArticlePage/LearningResourcePage/components/LearningResourcePanels.tsx index ab7a0400f4..72bfc1321b 100644 --- a/src/containers/ArticlePage/LearningResourcePage/components/LearningResourcePanels.tsx +++ b/src/containers/ArticlePage/LearningResourcePage/components/LearningResourcePanels.tsx @@ -6,28 +6,47 @@ * */ -import { useFormikContext } from "formik"; +import { useField, useFormikContext } from "formik"; import { memo, useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { PageContent } from "@ndla/primitives"; +import { PageContent, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { IUpdatedArticle, IArticle } from "@ndla/types-backend/draft-api"; import { Node, TaxonomyContext } from "@ndla/types-taxonomy"; import LearningResourceContent from "./LearningResourceContent"; import LearningResourceTaxonomy from "./LearningResourceTaxonomy"; import FormAccordion from "../../../../components/Accordion/FormAccordion"; -import FormAccordionsWithComments from "../../../../components/Accordion/FormAccordionsWithComments"; +import FormAccordions from "../../../../components/Accordion/FormAccordions"; +import QualityEvaluation from "../../../../components/QualityEvaluation/QualityEvaluation"; import { IsNewArticleLanguageProvider } from "../../../../components/SlateEditor/IsNewArticleLanguageProvider"; import config from "../../../../config"; -import { TAXONOMY_WRITE_SCOPE } from "../../../../constants"; +import { STORED_HIDE_COMMENTS, TAXONOMY_WRITE_SCOPE } from "../../../../constants"; import { CopyrightFieldGroup, VersionAndNotesPanel, MetaDataField } from "../../../FormikForm"; -import { HandleSubmitFunc, LearningResourceFormType } from "../../../FormikForm/articleFormHooks"; +import { ArticleFormType, HandleSubmitFunc, LearningResourceFormType } from "../../../FormikForm/articleFormHooks"; import GrepCodesField from "../../../FormikForm/GrepCodesField"; import { useSession } from "../../../Session/SessionProvider"; +import { useLocalStorageBooleanState } from "../../../WelcomePage/hooks/storedFilterHooks"; +import CommentSection, { RESET_COMMENTS_STATUSES } from "../../components/CommentSection"; import PanelTitleWithChangeIndicator from "../../components/PanelTitleWithChangeIndicator"; import RelatedContentFieldGroup from "../../components/RelatedContentFieldGroup"; import RevisionNotes from "../../components/RevisionNotes"; import { FlatArticleKeys } from "../../components/types"; +const StyledWrapper = styled("div", { + base: { + display: "grid", + gridTemplateColumns: "1fr auto", + }, +}); + +const StyledControls = styled("div", { + base: { + display: "flex", + gap: "small", + justifyContent: "space-between", + }, +}); + interface Props { article?: IArticle; articleHistory: IArticle[] | undefined; @@ -47,6 +66,8 @@ const LearningResourcePanels = ({ contexts, handleSubmit, }: Props) => { + const [hideComments, setHideComments] = useLocalStorageBooleanState(STORED_HIDE_COMMENTS); + const [revisionMetaField, , revisionMetaHelpers] = useField("revisionMeta"); const { t } = useTranslation(); const { userPermissions } = useSession(); const { errors } = useFormikContext(); @@ -57,102 +78,133 @@ const LearningResourcePanels = ({ [], ); const copyrightFields = useMemo(() => ["copyright"], []); + const removeComments = useMemo( + () => RESET_COMMENTS_STATUSES.some((s) => s === article?.status.current), + [article?.status], + ); return ( - - - } - hasError={!!(errors.title || errors.introduction || errors.content)} - > - - - - - - - {!!article && !!taxonomy && !!userPermissions?.includes(TAXONOMY_WRITE_SCOPE) && ( - - - - )} - - } - hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} - > - - - - - - - - - {config.ndlaEnvironment === "test" && ( - - - - )} - - - - {article && ( - - - - )} - + <> + + n.nodeType !== "TOPIC")} + revisionMetaField={revisionMetaField} + revisionMetaHelpers={revisionMetaHelpers} + updateNotes={updateNotes} + /> + {!removeComments && ( + setHideComments(!hideComments)}> + {t("form.comment.showComments")} + + + + + + )} + + + + + } + hasError={!!(errors.title || errors.introduction || errors.content)} + > + + + + + + + {!!article && !!taxonomy && !!userPermissions?.includes(TAXONOMY_WRITE_SCOPE) && ( + + + + )} + + } + hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} + > + + + + + + + + + {config.ndlaEnvironment === "test" && ( + + + + )} + + + + {article && ( + + + + )} + + {!hideComments && !removeComments && } + + ); }; diff --git a/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleAccordionPanels.tsx b/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleAccordionPanels.tsx index b6fcd57554..99a732fd64 100644 --- a/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleAccordionPanels.tsx +++ b/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleAccordionPanels.tsx @@ -9,24 +9,42 @@ import { useFormikContext } from "formik"; import { useMemo } from "react"; import { useTranslation } from "react-i18next"; -import { PageContent } from "@ndla/primitives"; +import { PageContent, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { IUpdatedArticle, IArticle } from "@ndla/types-backend/draft-api"; import TopicArticleContent from "./TopicArticleContent"; import TopicArticleTaxonomy from "./TopicArticleTaxonomy"; import FormAccordion from "../../../../components/Accordion/FormAccordion"; -import FormAccordionsWithComments from "../../../../components/Accordion/FormAccordionsWithComments"; +import FormAccordions from "../../../../components/Accordion/FormAccordions"; import config from "../../../../config"; -import { TAXONOMY_WRITE_SCOPE } from "../../../../constants"; +import { STORED_HIDE_COMMENTS, TAXONOMY_WRITE_SCOPE } from "../../../../constants"; import { CopyrightFieldGroup, VersionAndNotesPanel, MetaDataField } from "../../../FormikForm"; import { TopicArticleFormType } from "../../../FormikForm/articleFormHooks"; import GrepCodesField from "../../../FormikForm/GrepCodesField"; import { onSaveAsVisualElement } from "../../../FormikForm/utils"; import { useSession } from "../../../Session/SessionProvider"; +import { useLocalStorageBooleanState } from "../../../WelcomePage/hooks/storedFilterHooks"; +import CommentSection from "../../components/CommentSection"; import PanelTitleWithChangeIndicator from "../../components/PanelTitleWithChangeIndicator"; import RelatedContentFieldGroup from "../../components/RelatedContentFieldGroup"; import RevisionNotes from "../../components/RevisionNotes"; import { FlatArticleKeys } from "../../components/types"; +const StyledWrapper = styled("div", { + base: { + display: "grid", + gridTemplateColumns: "1fr auto", + }, +}); + +const StyledControls = styled("div", { + base: { + display: "flex", + gap: "small", + justifyContent: "flex-end", + }, +}); + interface Props { article?: IArticle; articleHistory: IArticle[] | undefined; @@ -42,6 +60,7 @@ const TopicArticleAccordionPanels = ({ articleLanguage, hasTaxonomyEntries, }: Props) => { + const [hideComments, setHideComments] = useLocalStorageBooleanState(STORED_HIDE_COMMENTS); const { t } = useTranslation(); const { userPermissions } = useSession(); const formikContext = useFormikContext(); @@ -53,88 +72,106 @@ const TopicArticleAccordionPanels = ({ const { values, errors } = formikContext; return ( - - - } - hasError={!!(errors.title || errors.introduction || errors.content || errors.visualElement)} - > - - - - - {article && !!userPermissions?.includes(TAXONOMY_WRITE_SCOPE) && ( - - - - )} - - } - hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} - > - - - - onSaveAsVisualElement(image, formikContext)} - /> - - - - - {config.ndlaEnvironment === "test" && ( - - - - )} - - - - {article && ( - - - - )} - + <> + + setHideComments(!hideComments)}> + {t("form.comment.showComments")} + + + + + + + + + + } + hasError={!!(errors.title || errors.introduction || errors.content || errors.visualElement)} + > + + + + + {article && !!userPermissions?.includes(TAXONOMY_WRITE_SCOPE) && ( + + + + )} + + } + hasError={!!(errors.creators || errors.rightsholders || errors.processors || errors.license)} + > + + + + onSaveAsVisualElement(image, formikContext)} + /> + + + + + {config.ndlaEnvironment === "test" && ( + + + + )} + + + + {article && ( + + + + )} + + {!hideComments && } + + ); }; diff --git a/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleForm.tsx b/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleForm.tsx index ae39a9fd8d..03bda2a938 100644 --- a/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleForm.tsx +++ b/src/containers/ArticlePage/TopicArticlePage/components/TopicArticleForm.tsx @@ -15,11 +15,10 @@ import { IUpdatedArticle, IArticle, IStatus, ILicense } from "@ndla/types-backen import { Node } from "@ndla/types-taxonomy"; import TopicArticleAccordionPanels from "./TopicArticleAccordionPanels"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import { FormActionsContainer } from "../../../../components/FormikForm"; +import { Form, FormActionsContainer } from "../../../../components/FormikForm"; import validateFormik, { getWarnings } from "../../../../components/formikValidationSchema"; import HeaderWithLanguage from "../../../../components/HeaderWithLanguage"; import EditorFooter from "../../../../components/SlateEditor/EditorFooter"; -import StyledForm from "../../../../components/StyledFormComponents"; import { ARCHIVED, UNPUBLISHED } from "../../../../constants"; import { validateDraft } from "../../../../modules/draft/draftApi"; import { useLicenses, useDraftStatusStateMachine } from "../../../../modules/draft/draftQueries"; @@ -118,7 +117,7 @@ const TopicArticleForm = ({ validate={validate} initialStatus={initialWarnings} > - +
- + ); }; diff --git a/src/containers/ArticlePage/components/CommentSection.tsx b/src/containers/ArticlePage/components/CommentSection.tsx index 1c85db2e35..c65dbc7250 100644 --- a/src/containers/ArticlePage/components/CommentSection.tsx +++ b/src/containers/ArticlePage/components/CommentSection.tsx @@ -8,15 +8,12 @@ import { FastField, FieldArray, FieldProps, useField, useFormikContext } from "formik"; import { memo } from "react"; -import { spacing } from "@ndla/core"; import { styled } from "@ndla/styled-system/jsx"; import Comment, { CommentType } from "./Comment"; import InputComment from "./InputComment"; import { ARCHIVED, PUBLISHED, UNPUBLISHED } from "../../../constants"; export const RESET_COMMENTS_STATUSES = [PUBLISHED, ARCHIVED, UNPUBLISHED]; -export const COMMENT_WIDTH = 220; -export const SPACING_COMMENT = Number(spacing.small.replace("px", "")); const StyledList = styled("ul", { base: { @@ -29,6 +26,9 @@ const StyledCommentWrapper = styled("div", { display: "flex", flexDirection: "column", gap: "large", + // TODO: Consider using value from semantic tokens or adding this as a semantic token + width: "220px", + marginInlineStart: "small", }, }); diff --git a/src/containers/ArticlePage/styles.ts b/src/containers/ArticlePage/styles.ts deleted file mode 100644 index 7e2d53db55..0000000000 --- a/src/containers/ArticlePage/styles.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) 2023-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { COMMENT_WIDTH, SPACING_COMMENT } from "./components/CommentSection"; -import { MAX_FRONTPAGE_ARTICLE_WIDTH, MAX_PAGE_WIDTH } from "../../constants"; - -// Calculate the max width of edit resource page with comments displayed -export const MAX_WIDTH_WITH_COMMENTS = MAX_PAGE_WIDTH + COMMENT_WIDTH + SPACING_COMMENT; - -export const MAX_WIDTH_FRONTPAGE_WITH_COMMENTS = MAX_FRONTPAGE_ARTICLE_WIDTH + COMMENT_WIDTH + SPACING_COMMENT; diff --git a/src/containers/AudioUploader/components/AudioForm.tsx b/src/containers/AudioUploader/components/AudioForm.tsx index 09046b9232..8bfab3fefa 100644 --- a/src/containers/AudioUploader/components/AudioForm.tsx +++ b/src/containers/AudioUploader/components/AudioForm.tsx @@ -12,7 +12,6 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { Descendant } from "slate"; import { Button, PageContent } from "@ndla/primitives"; -import { styled } from "@ndla/styled-system/jsx"; import { IAudio, IAuthor, @@ -26,9 +25,8 @@ import AudioManuscript from "./AudioManuscript"; import AudioMetaData from "./AudioMetaData"; import FormAccordion from "../../../components/Accordion/FormAccordion"; import FormAccordions from "../../../components/Accordion/FormAccordions"; -import { FormActionsContainer } from "../../../components/FormikForm"; +import { FormActionsContainer, Form } from "../../../components/FormikForm"; import validateFormik, { getWarnings, RulesType } from "../../../components/formikValidationSchema"; -import FormWrapper from "../../../components/FormWrapper"; import HeaderWithLanguage from "../../../components/HeaderWithLanguage"; import SaveButton from "../../../components/SaveButton"; import { SAVE_BUTTON_ID } from "../../../constants"; @@ -62,12 +60,6 @@ export interface AudioFormikType { license: string; } -const StyledFormActionsContainer = styled(FormActionsContainer, { - base: { - marginBlockStart: "xsmall", - }, -}); - const rules: RulesType = { title: { required: true, @@ -206,7 +198,7 @@ const AudioForm = ({ return errFields.some((field) => !!errors[field]); }; return ( - +
- + @@ -261,14 +253,14 @@ const AudioForm = ({ submitForm(); }} /> - + - + ); }} diff --git a/src/containers/EditSubjectFrontpage/components/SubjectpageForm.tsx b/src/containers/EditSubjectFrontpage/components/SubjectpageForm.tsx index 96c237474b..50c0f3f5d1 100644 --- a/src/containers/EditSubjectFrontpage/components/SubjectpageForm.tsx +++ b/src/containers/EditSubjectFrontpage/components/SubjectpageForm.tsx @@ -9,8 +9,6 @@ import { Formik, FormikProps } from "formik"; import { useState } from "react"; import { useTranslation } from "react-i18next"; - -import { styled } from "@ndla/styled-system/jsx"; import { IArticle } from "@ndla/types-backend/draft-api"; import { ISubjectPageData, @@ -18,14 +16,12 @@ import { IUpdatedSubjectFrontPageData, } from "@ndla/types-backend/frontpage-api"; import { ILearningPathV2 } from "@ndla/types-backend/learningpath-api"; - import SubjectpageAccordionPanels from "./SubjectpageAccordionPanels"; -import { FormActionsContainer } from "../../../components/FormikForm"; +import { FormActionsContainer, Form } from "../../../components/FormikForm"; import validateFormik, { RulesType } from "../../../components/formikValidationSchema"; import SimpleLanguageHeader from "../../../components/HeaderWithLanguage/SimpleLanguageHeader"; import SaveButton from "../../../components/SaveButton"; import { isSlateEmbed } from "../../../components/SlateEditor/plugins/embed/utils"; -import StyledForm from "../../../components/StyledFormComponents"; import { SAVE_BUTTON_ID } from "../../../constants"; import { fetchNodes } from "../../../modules/nodes/nodeApi"; import { isFormikFormDirty } from "../../../util/formHelper"; @@ -42,12 +38,6 @@ import usePreventWindowUnload from "../../FormikForm/preventWindowUnloadHook"; import { useMessages } from "../../Messages/MessagesProvider"; import { useTaxonomyVersion } from "../../StructureVersion/TaxonomyVersionProvider"; -const StyledFormActionsContainer = styled(FormActionsContainer, { - base: { - marginBlockStart: "xsmall", - }, -}); - interface Props { subjectpage?: ISubjectPageData; editorsChoices?: (IArticle | ILearningPathV2)[]; @@ -189,7 +179,7 @@ const SubjectpageForm = ({ }); setUnsaved(formIsDirty); return ( - +
toEditSubjectpage(values.elementId!, lang, values.id)} @@ -207,7 +197,7 @@ const SubjectpageForm = ({ errors={errors} leadsTo={values.leadsTo} /> - + handleSubmit(formik)} disabled={!isValid} /> - + - + ); }} diff --git a/src/containers/NdlaFilm/components/NdlaFilmForm.tsx b/src/containers/NdlaFilm/components/NdlaFilmForm.tsx index b3cf0faec7..59a744b80e 100644 --- a/src/containers/NdlaFilm/components/NdlaFilmForm.tsx +++ b/src/containers/NdlaFilm/components/NdlaFilmForm.tsx @@ -11,19 +11,17 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { Descendant } from "slate"; import { PageContent } from "@ndla/primitives"; -import { styled } from "@ndla/styled-system/jsx"; import { IFilmFrontPageData, IMovieTheme } from "@ndla/types-backend/frontpage-api"; import NdlaFilmArticle from "./NdlaFilmArticle"; import SlideshowEditor from "./SlideshowEditor"; import ThemeEditor from "./ThemeEditor"; import FormAccordion from "../../../components/Accordion/FormAccordion"; import FormAccordions from "../../../components/Accordion/FormAccordions"; -import { FormActionsContainer } from "../../../components/FormikForm"; +import { FormActionsContainer, Form } from "../../../components/FormikForm"; import validateFormik, { RulesType } from "../../../components/formikValidationSchema"; import SimpleLanguageHeader from "../../../components/HeaderWithLanguage/SimpleLanguageHeader"; import SaveButton from "../../../components/SaveButton"; import { isSlateEmbed } from "../../../components/SlateEditor/plugins/embed/utils"; -import StyledForm from "../../../components/StyledFormComponents"; import { SAVE_BUTTON_ID } from "../../../constants"; import { useUpdateFilmFrontpageMutation } from "../../../modules/frontpage/filmMutations"; import { isFormikFormDirty } from "../../../util/formHelper"; @@ -35,12 +33,6 @@ import { AlertDialogWrapper } from "../../FormikForm"; import usePreventWindowUnload from "../../FormikForm/preventWindowUnloadHook"; import { useMessages } from "../../Messages/MessagesProvider"; -const StyledFormActionsContainer = styled(FormActionsContainer, { - base: { - marginBlockStart: "xsmall", - }, -}); - interface Props { filmFrontpage: IFilmFrontPageData; selectedLanguage: string; @@ -128,7 +120,7 @@ const NdlaFilmForm = ({ filmFrontpage, selectedLanguage }: Props) => { }); setUnsaved(formIsDirty); return ( - +
toEditNdlaFilm(lang)} @@ -159,7 +151,7 @@ const NdlaFilmForm = ({ filmFrontpage, selectedLanguage }: Props) => { - + { onClick={submitForm} disabled={!isValid} /> - + - + ); }} diff --git a/src/containers/PreviewDraftPage/LanguageSelector.tsx b/src/containers/PreviewDraftPage/LanguageSelector.tsx index ac1b0a9894..af4db8aabd 100644 --- a/src/containers/PreviewDraftPage/LanguageSelector.tsx +++ b/src/containers/PreviewDraftPage/LanguageSelector.tsx @@ -9,18 +9,12 @@ import { useTranslation } from "react-i18next"; import { useNavigate, useParams } from "react-router-dom"; import styled from "@emotion/styled"; -import { MAX_FRONTPAGE_ARTICLE_WIDTH } from "../../constants"; import { toPreviewDraft } from "../../util/routeHelpers"; const StyledSelect = styled.select` - max-width: 972px; margin: 0 auto; width: 100%; display: block; - - &[data-wide="true"] { - max-width: ${MAX_FRONTPAGE_ARTICLE_WIDTH}px; - } `; interface Props { From 50d3db10d9e47b79a99fd0d3df6da36427e31e21 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Thu, 14 Nov 2024 11:05:04 +0100 Subject: [PATCH 005/170] Simplify and refactor StructureContainer layout styling to panda --- src/components/Layout/Layout.tsx | 41 ---------- .../StructurePage/StructureContainer.tsx | 81 ++++++++++--------- 2 files changed, 42 insertions(+), 80 deletions(-) delete mode 100644 src/components/Layout/Layout.tsx diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx deleted file mode 100644 index a1386bd4a5..0000000000 --- a/src/components/Layout/Layout.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2023-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import styled from "@emotion/styled"; -import { spacing, mq } from "@ndla/core"; - -export const GRID_GAP = spacing.nsmall; - -export const GridContainer = styled.div<{ breakpoint?: string }>` - ${({ breakpoint }) => breakpoint && mq.range({ from: "0px", until: breakpoint })} { - padding: 0 ${GRID_GAP}; - display: flex; - flex-direction: column; - gap: ${GRID_GAP}; - } - - ${({ breakpoint }) => mq.range({ from: breakpoint ?? "0px" })} { - display: grid; - grid-template-columns: repeat(12, 1fr); - grid-gap: ${GRID_GAP}; - max-width: 1400px; - justify-self: center; - align-self: center; - width: 100%; - padding: 0 ${spacing.nsmall}; - } -`; -interface ColumnSize { - colStart?: number; - colEnd?: number; -} - -export const Column = styled.div` - grid-column: ${(props) => `${props.colStart ?? 1} / ${props.colEnd ?? 13}`}; - min-width: 400px; -`; diff --git a/src/containers/StructurePage/StructureContainer.tsx b/src/containers/StructurePage/StructureContainer.tsx index bccb0a76cd..c0ba60adb5 100644 --- a/src/containers/StructurePage/StructureContainer.tsx +++ b/src/containers/StructurePage/StructureContainer.tsx @@ -10,9 +10,8 @@ import keyBy from "lodash/keyBy"; import { useEffect, useRef, useState, ReactNode, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; -import styled from "@emotion/styled"; -import { breakpoints, spacing } from "@ndla/core"; -import { Spinner } from "@ndla/primitives"; +import { PageContent, Spinner } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { NodeChild, Node, NodeType } from "@ndla/types-taxonomy"; import StructureErrorIcon from "./folderComponents/StructureErrorIcon"; import StructureResources from "./resourceComponents/StructureResources"; @@ -21,7 +20,6 @@ import RootNode from "./RootNode"; import StructureBanner from "./StructureBanner"; import VersionSelector from "./VersionSelector"; import ErrorBoundary from "../../components/ErrorBoundary"; -import { GridContainer, Column } from "../../components/Layout/Layout"; import { REMEMBER_DA_SUBJECTS, REMEMBER_FAVORITE_NODES, @@ -43,29 +41,34 @@ import { useTaxonomyVersion } from "../StructureVersion/TaxonomyVersionProvider" import { useLocalStorageBooleanState } from "../WelcomePage/hooks/storedFilterHooks"; import { getResultSubjectIdObject } from "../WelcomePage/utils"; -const StructureWrapper = styled.ul` - margin: 0; - padding: 0; -`; +const StickyContainer = styled("div", { + base: { + position: "sticky", + top: "xsmall", + }, +}); -const StickyContainer = styled.div` - position: sticky; - top: ${spacing.small}; -`; - -const isChildNode = createGuard("connectionId"); +const GridWrapper = styled("div", { + base: { + display: "grid", + gridTemplateColumns: "repeat(2, minmax(0, 1fr))", + gap: "xsmall", + paddingBlock: "xsmall", + desktopDown: { + display: "flex", + flexDirection: "column", + gap: "xsmall", + }, + }, +}); -const StyledStructureContainer = styled.div` - position: relative; -`; +const MessageBoxWrapper = styled("div", { + base: { + gridColumn: "1/-1", + }, +}); -const Wrapper = styled.div` - display: flex; - flex-direction: column; - justify-content: space-between; - flex: 1; - padding-block-start: ${spacing.nsmall}; -`; +const isChildNode = createGuard("connectionId"); const getNodes = ( allNodes: Node[] | undefined = [], @@ -199,10 +202,10 @@ const StructureContainer = ({ return ( - - - {messageBox && {messageBox}} - + + + {messageBox && {messageBox}} +
- + <> {userDataQuery.isLoading || nodesQuery.isLoading ? ( ) : ( - +
{nodes!.map((node) => ( ))} - +
)} -
- + +
{showResourceColumn && ( - +
{currentNode && ( {currentNode.nodeType === "SUBJECT" && ( @@ -260,12 +263,12 @@ const StructureContainer = ({ )} )} - +
)} -
- {isTaxonomyAdmin && } -
- + + + {isTaxonomyAdmin && } +
); }; From cae11672196fc2ae7f25996cc27b8c1524400ba4 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Mon, 18 Nov 2024 10:42:06 +0100 Subject: [PATCH 006/170] Fix correct language redirect when language does not exist --- .../resourceComponents/TopicResourceBanner.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx b/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx index 6ab3688edf..1a5693b018 100644 --- a/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx +++ b/src/containers/StructurePage/resourceComponents/TopicResourceBanner.tsx @@ -192,7 +192,12 @@ const TopicResourceBanner = ({ {numericId ? ( Date: Mon, 18 Nov 2024 11:48:27 +0100 Subject: [PATCH 007/170] Fix react unique key warnings in slate plugins --- .../SlateEditor/plugins/audio/index.tsx | 2 +- .../SlateEditor/plugins/blockquote/index.tsx | 2 +- .../plugins/campaignBlock/index.tsx | 2 +- .../SlateEditor/plugins/codeBlock/index.tsx | 2 +- .../plugins/comment/block/index.tsx | 2 +- .../plugins/comment/inline/index.tsx | 2 +- .../plugins/concept/block/index.tsx | 2 +- .../plugins/concept/inline/index.tsx | 2 +- .../plugins/contactBlock/index.tsx | 2 +- .../SlateEditor/plugins/copyright/index.ts | 2 +- .../SlateEditor/plugins/embed/index.tsx | 2 +- .../SlateEditor/plugins/external/index.ts | 2 +- .../SlateEditor/plugins/file/index.tsx | 6 +- .../SlateEditor/plugins/footnote/index.tsx | 2 +- .../plugins/framedContent/index.tsx | 8 ++- .../SlateEditor/plugins/h5p/index.tsx | 2 +- .../SlateEditor/plugins/image/index.ts | 2 +- .../SlateEditor/plugins/keyFigure/index.tsx | 2 +- .../plugins/linkBlockList/index.tsx | 3 +- .../SlateEditor/plugins/pitch/index.tsx | 2 +- .../SlateEditor/plugins/related/index.tsx | 7 +- .../SlateEditor/plugins/uuDisclaimer/index.ts | 2 +- .../SlateEditor/plugins/video/index.ts | 2 +- src/util/__tests__/embedTagHelpers-test.ts | 71 +++++++++++-------- src/util/articleContentConverter.tsx | 4 +- src/util/embedTagHelpers.tsx | 22 +++--- 26 files changed, 94 insertions(+), 65 deletions(-) diff --git a/src/components/SlateEditor/plugins/audio/index.tsx b/src/components/SlateEditor/plugins/audio/index.tsx index 0a8659711d..64878eeb19 100644 --- a/src/components/SlateEditor/plugins/audio/index.tsx +++ b/src/components/SlateEditor/plugins/audio/index.tsx @@ -37,7 +37,7 @@ export const audioSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_AUDIO || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/blockquote/index.tsx b/src/components/SlateEditor/plugins/blockquote/index.tsx index b8987906fc..9133bac51c 100644 --- a/src/components/SlateEditor/plugins/blockquote/index.tsx +++ b/src/components/SlateEditor/plugins/blockquote/index.tsx @@ -37,7 +37,7 @@ export const blockQuoteSerializer: SlateSerializer = { serialize(node: Descendant, children: JSX.Element[]) { if (!Element.isElement(node)) return; if (node.type === TYPE_QUOTE) { - return createTag("blockquote", node.data, children, { bailOnEmptyData: false }); + return createTag("blockquote", node.data, children, { bailOnEmptyData: false }, undefined); } }, }; diff --git a/src/components/SlateEditor/plugins/campaignBlock/index.tsx b/src/components/SlateEditor/plugins/campaignBlock/index.tsx index 76e34302dc..af4dd53723 100644 --- a/src/components/SlateEditor/plugins/campaignBlock/index.tsx +++ b/src/components/SlateEditor/plugins/campaignBlock/index.tsx @@ -45,7 +45,7 @@ export const campaignBlockSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_CAMPAIGN_BLOCK || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/codeBlock/index.tsx b/src/components/SlateEditor/plugins/codeBlock/index.tsx index 80f9f56371..066156f19a 100644 --- a/src/components/SlateEditor/plugins/codeBlock/index.tsx +++ b/src/components/SlateEditor/plugins/codeBlock/index.tsx @@ -45,7 +45,7 @@ export const codeblockSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== "code-block") return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/comment/block/index.tsx b/src/components/SlateEditor/plugins/comment/block/index.tsx index de85c8db53..f47c178619 100644 --- a/src/components/SlateEditor/plugins/comment/block/index.tsx +++ b/src/components/SlateEditor/plugins/comment/block/index.tsx @@ -38,7 +38,7 @@ export const commentBlockSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_COMMENT_BLOCK || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/comment/inline/index.tsx b/src/components/SlateEditor/plugins/comment/inline/index.tsx index 162db8f166..c3c0c7689f 100644 --- a/src/components/SlateEditor/plugins/comment/inline/index.tsx +++ b/src/components/SlateEditor/plugins/comment/inline/index.tsx @@ -32,7 +32,7 @@ export const commentInlineSerializer: SlateSerializer = { }, serialize(node: Descendant, children: JSX.Element[]) { if (!Element.isElement(node) || node.type !== TYPE_COMMENT_INLINE || !node.data) return; - return createEmbedTagV2(node.data, children); + return createEmbedTagV2(node.data, children, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/concept/block/index.tsx b/src/components/SlateEditor/plugins/concept/block/index.tsx index 54af63df91..c923c52858 100644 --- a/src/components/SlateEditor/plugins/concept/block/index.tsx +++ b/src/components/SlateEditor/plugins/concept/block/index.tsx @@ -44,7 +44,7 @@ export const blockConceptSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_CONCEPT_BLOCK) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/concept/inline/index.tsx b/src/components/SlateEditor/plugins/concept/inline/index.tsx index 6860552a58..b44ba739cf 100644 --- a/src/components/SlateEditor/plugins/concept/inline/index.tsx +++ b/src/components/SlateEditor/plugins/concept/inline/index.tsx @@ -42,7 +42,7 @@ export const inlineConceptSerializer: SlateSerializer = { linkText: Node.string(node), }; - return createEmbedTagV2(data); + return createEmbedTagV2(data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/contactBlock/index.tsx b/src/components/SlateEditor/plugins/contactBlock/index.tsx index 797d732dd8..099eb00eed 100644 --- a/src/components/SlateEditor/plugins/contactBlock/index.tsx +++ b/src/components/SlateEditor/plugins/contactBlock/index.tsx @@ -45,7 +45,7 @@ export const contactBlockSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_CONTACT_BLOCK || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/copyright/index.ts b/src/components/SlateEditor/plugins/copyright/index.ts index 7c94eca4e0..7247df7aee 100644 --- a/src/components/SlateEditor/plugins/copyright/index.ts +++ b/src/components/SlateEditor/plugins/copyright/index.ts @@ -36,7 +36,7 @@ export const copyrightSerializer: SlateSerializer = { }, serialize(node: Descendant, children: JSX.Element[]) { if (!Element.isElement(node) || node.type !== TYPE_COPYRIGHT || !node.data) return; - return createEmbedTagV2({ ...node.data, copyright: JSON.stringify(node.data.copyright) }, children); + return createEmbedTagV2({ ...node.data, copyright: JSON.stringify(node.data.copyright) }, children, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/embed/index.tsx b/src/components/SlateEditor/plugins/embed/index.tsx index c6196cf49b..dc475961a3 100644 --- a/src/components/SlateEditor/plugins/embed/index.tsx +++ b/src/components/SlateEditor/plugins/embed/index.tsx @@ -46,7 +46,7 @@ export const embedSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || !isSlateEmbed(node)) return; - return createEmbedTag(node.data); + return createEmbedTag(node.data, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/external/index.ts b/src/components/SlateEditor/plugins/external/index.ts index f267f2dda2..0cbe69b666 100644 --- a/src/components/SlateEditor/plugins/external/index.ts +++ b/src/components/SlateEditor/plugins/external/index.ts @@ -38,7 +38,7 @@ export const externalSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (Element.isElement(node) && (node.type === TYPE_EXTERNAL || node.type === TYPE_IFRAME) && node.data) { - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); } }, }; diff --git a/src/components/SlateEditor/plugins/file/index.tsx b/src/components/SlateEditor/plugins/file/index.tsx index 73e85094b1..7199a4557d 100644 --- a/src/components/SlateEditor/plugins/file/index.tsx +++ b/src/components/SlateEditor/plugins/file/index.tsx @@ -7,10 +7,11 @@ */ import { Descendant, Editor, Element } from "slate"; +import { uuid } from "@ndla/util"; import { TYPE_FILE } from "./types"; import { defaultFileBlock } from "./utils"; import { File } from "../../../../interfaces"; -import { createEmbedTag } from "../../../../util/embedTagHelpers"; +import { createEmbedTag, createEmbedTagV2 } from "../../../../util/embedTagHelpers"; import { SlateSerializer } from "../../interfaces"; import { defaultBlockNormalizer, NormalizerConfig } from "../../utils/defaultNormalizer"; import { afterOrBeforeTextBlockElement } from "../../utils/normalizationHelpers"; @@ -47,7 +48,8 @@ export const fileSerializer: SlateSerializer = { serialize(node: Descendant) { if (!Element.isElement(node)) return; if (node.type !== TYPE_FILE) return; - return
{node.data.map((file) => createEmbedTag(file))}
; + const children = node.data.map((file) => createEmbedTag(file, file.path)); + return
{children}
; }, }; diff --git a/src/components/SlateEditor/plugins/footnote/index.tsx b/src/components/SlateEditor/plugins/footnote/index.tsx index a072c59bb3..e52b7d7dee 100644 --- a/src/components/SlateEditor/plugins/footnote/index.tsx +++ b/src/components/SlateEditor/plugins/footnote/index.tsx @@ -55,7 +55,7 @@ export const footnoteSerializer: SlateSerializer = { authors: node.data.authors ? node.data.authors.join(";") : "", }; - return createEmbedTag(data); + return createEmbedTag(data, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/framedContent/index.tsx b/src/components/SlateEditor/plugins/framedContent/index.tsx index dda702e995..631209dc35 100644 --- a/src/components/SlateEditor/plugins/framedContent/index.tsx +++ b/src/components/SlateEditor/plugins/framedContent/index.tsx @@ -66,7 +66,13 @@ export const framedContentSerializer: SlateSerializer = { }, serialize(node: Descendant, children: JSX.Element[]) { if (!Element.isElement(node) || node.type !== TYPE_FRAMED_CONTENT) return; - return createTag("div", { ...node.data, type: TYPE_FRAMED_CONTENT }, children, { bailOnEmptyData: false }); + return createTag( + "div", + { ...node.data, type: TYPE_FRAMED_CONTENT }, + children, + { bailOnEmptyData: false }, + undefined, + ); }, }; diff --git a/src/components/SlateEditor/plugins/h5p/index.tsx b/src/components/SlateEditor/plugins/h5p/index.tsx index 54bcfdd495..4dd6a8442f 100644 --- a/src/components/SlateEditor/plugins/h5p/index.tsx +++ b/src/components/SlateEditor/plugins/h5p/index.tsx @@ -37,7 +37,7 @@ export const h5pSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_H5P || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/image/index.ts b/src/components/SlateEditor/plugins/image/index.ts index e05370c834..3d1eb27d87 100644 --- a/src/components/SlateEditor/plugins/image/index.ts +++ b/src/components/SlateEditor/plugins/image/index.ts @@ -37,7 +37,7 @@ export const imageSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_IMAGE || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/keyFigure/index.tsx b/src/components/SlateEditor/plugins/keyFigure/index.tsx index ed03ff8a9b..79e50b4347 100644 --- a/src/components/SlateEditor/plugins/keyFigure/index.tsx +++ b/src/components/SlateEditor/plugins/keyFigure/index.tsx @@ -48,7 +48,7 @@ export const keyFigureSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_KEY_FIGURE || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/linkBlockList/index.tsx b/src/components/SlateEditor/plugins/linkBlockList/index.tsx index a6a9a981ba..3d634527d0 100644 --- a/src/components/SlateEditor/plugins/linkBlockList/index.tsx +++ b/src/components/SlateEditor/plugins/linkBlockList/index.tsx @@ -44,7 +44,8 @@ export const linkBlockListSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_LINK_BLOCK_LIST) return; - return ; + const children = node.data?.map((child) => createEmbedTagV2(child, undefined, child.url)); + return ; }, }; diff --git a/src/components/SlateEditor/plugins/pitch/index.tsx b/src/components/SlateEditor/plugins/pitch/index.tsx index 4da7d19790..8b9d156195 100644 --- a/src/components/SlateEditor/plugins/pitch/index.tsx +++ b/src/components/SlateEditor/plugins/pitch/index.tsx @@ -44,7 +44,7 @@ export const pitchSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_PITCH || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/related/index.tsx b/src/components/SlateEditor/plugins/related/index.tsx index ffb2045968..1d81a83d10 100644 --- a/src/components/SlateEditor/plugins/related/index.tsx +++ b/src/components/SlateEditor/plugins/related/index.tsx @@ -63,7 +63,12 @@ export const relatedSerializer: SlateSerializer = { serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_RELATED) return; - return
{node.data.map((child) => createEmbedTagV2(child))}
; + const children = node.data.map((child) => { + const key = child.articleId ? child.articleId : child.url; + return createEmbedTagV2(child, undefined, key); + }); + + return
{children}
; }, }; diff --git a/src/components/SlateEditor/plugins/uuDisclaimer/index.ts b/src/components/SlateEditor/plugins/uuDisclaimer/index.ts index 030fe6f823..23b25ff346 100644 --- a/src/components/SlateEditor/plugins/uuDisclaimer/index.ts +++ b/src/components/SlateEditor/plugins/uuDisclaimer/index.ts @@ -26,7 +26,7 @@ export const disclaimerSerializer: SlateSerializer = { }, serialize(node: Descendant, children: JSX.Element[]) { if (!Element.isElement(node) || node.type !== TYPE_DISCLAIMER || !node.data) return; - return createEmbedTagV2(node.data, children); + return createEmbedTagV2(node.data, children, undefined); }, }; diff --git a/src/components/SlateEditor/plugins/video/index.ts b/src/components/SlateEditor/plugins/video/index.ts index e85ae5425d..8c5375f7f9 100644 --- a/src/components/SlateEditor/plugins/video/index.ts +++ b/src/components/SlateEditor/plugins/video/index.ts @@ -37,7 +37,7 @@ export const embedSerializer: SlateSerializer = { }, serialize(node: Descendant) { if (!Element.isElement(node) || node.type !== TYPE_EMBED_BRIGHTCOVE || !node.data) return; - return createEmbedTagV2(node.data); + return createEmbedTagV2(node.data, undefined, undefined); }, }; diff --git a/src/util/__tests__/embedTagHelpers-test.ts b/src/util/__tests__/embedTagHelpers-test.ts index dbdf6d6920..eb97f5841f 100644 --- a/src/util/__tests__/embedTagHelpers-test.ts +++ b/src/util/__tests__/embedTagHelpers-test.ts @@ -63,16 +63,19 @@ test("parseEmbedTag parses related-content embed tag to object", () => { }); test("createEmbedTag creates image embed tag from object", () => { - const tag = createEmbedTag({ - align: "", - alt: "Guinness sign", - caption: "Guinness is good for you", - metaData: {}, - resource: "image", - resource_id: "42159", - size: "full", - url: "https://api.ndla.no/image-api/v3/images/42159", - }); + const tag = createEmbedTag( + { + align: "", + alt: "Guinness sign", + caption: "Guinness is good for you", + metaData: {}, + resource: "image", + resource_id: "42159", + size: "full", + url: "https://api.ndla.no/image-api/v3/images/42159", + }, + undefined, + ); expect(tag).toMatchSnapshot(); }); @@ -86,15 +89,18 @@ test("createEmbedTagV2 creates image embed tag from object", () => { size: "full", url: "https://api.ndla.no/image-api/v3/images/42159", }; - expect(createEmbedTag(data)).toEqual(createEmbedTagV2(data)); + expect(createEmbedTag(data, undefined)).toEqual(createEmbedTagV2(data, undefined, undefined)); }); test("createEmbedTag creates h5p embed tag from object", () => { - const tag = createEmbedTag({ - metaData: {}, - resource: "h5p", - url: "https://h5p-test.ndla.no/resource/3ab6850d/oembed", - }); + const tag = createEmbedTag( + { + metaData: {}, + resource: "h5p", + url: "https://h5p-test.ndla.no/resource/3ab6850d/oembed", + }, + undefined, + ); expect(tag).toMatchSnapshot(); }); @@ -105,7 +111,7 @@ test("createEmbedTagV2 creates h5p embed tag from object", () => { url: "https://h5p-test.ndla.no/resource/3ab6850d/oembed", }; - const tag = createEmbedTagV2(data); + const tag = createEmbedTagV2(data, undefined, undefined); expect(tag).toMatchSnapshot(); }); @@ -118,20 +124,23 @@ test("createEmbedTagV2 filters out null and undefined values, but not false valu videoid: "123", }; - const tag = createEmbedTagV2(data); + const tag = createEmbedTagV2(data, undefined, undefined); expect(tag).toMatchSnapshot(); }); test("createEmbedTag creates brightcove embed tag from object", () => { - const tag = createEmbedTag({ - account: "4806596774001", - caption: "Intervju med Hallvard", - metaData: {}, - player: "BkLm8fT", - resource: "brightcove", - videoid: "ref:106952", - }); + const tag = createEmbedTag( + { + account: "4806596774001", + caption: "Intervju med Hallvard", + metaData: {}, + player: "BkLm8fT", + resource: "brightcove", + videoid: "ref:106952", + }, + undefined, + ); expect(tag).toMatchSnapshot(); }); @@ -144,7 +153,7 @@ test("createEmbedTagV2 converts camel-case to kebab-case", () => { url: "https://api.test.ndla.no/audio-api/v1/audio/3000", }; - const tag = createEmbedTagV2(data); + const tag = createEmbedTagV2(data, undefined, undefined); expect(tag).toMatchSnapshot(); }); @@ -156,17 +165,17 @@ test("createEmbedTagV2 creates brightcove embed tag from object", () => { resource: "brightcove", videoid: "ref:106952", }; - const tag = createEmbedTagV2(data); + const tag = createEmbedTagV2(data, undefined, undefined); - expect(tag).toEqual(createEmbedTag(data)); + expect(tag).toEqual(createEmbedTag(data, undefined)); }); test("createEmbedTag returns undefined if the object contains no keys", () => { - expect(createEmbedTag({})).toBe(undefined); + expect(createEmbedTag({}, undefined)).toBe(undefined); }); test("createEmbedTagV2 returns undefined if the object contains no keys", () => { - expect(createEmbedTagV2({})).toBe(undefined); + expect(createEmbedTagV2({}, undefined, undefined)).toBe(undefined); }); test("isUserProvidedEmbedDataValid for image", () => { diff --git a/src/util/articleContentConverter.tsx b/src/util/articleContentConverter.tsx index 3e1053198d..9907c9194e 100644 --- a/src/util/articleContentConverter.tsx +++ b/src/util/articleContentConverter.tsx @@ -271,8 +271,8 @@ export function editorValueToEmbedTag(editorValue?: Descendant[]) { if (embed) { const embedTag = embed?.resource === "audio" || embed?.resource === "image" - ? createEmbedTagV2(embed) - : createEmbedTag(embed); + ? createEmbedTagV2(embed, undefined, undefined) + : createEmbedTag(embed, undefined); return embedTag ? renderToStaticMarkup(embedTag) : ""; } return ""; diff --git a/src/util/embedTagHelpers.tsx b/src/util/embedTagHelpers.tsx index 99c7d02bec..bd134f888b 100644 --- a/src/util/embedTagHelpers.tsx +++ b/src/util/embedTagHelpers.tsx @@ -134,9 +134,10 @@ export const createDataAttributes = ( Tag: ElementType, - data?: EmbedProps, - children?: ReactNode[], - opts?: { bailOnEmptyData?: boolean }, + data: EmbedProps | undefined, + children: ReactNode[] | undefined, + opts: { bailOnEmptyData?: boolean }, + key: string | undefined, ): JSX.Element | undefined => { const dataAttributes = createDataAttributes(data, opts?.bailOnEmptyData); // dataAttributes is undefined if bailOnEmptyData is true and data is empty @@ -144,15 +145,20 @@ export const createTag = ( return undefined; } - return {children}; + return ( + + {children} + + ); }; export const createEmbedTagV2 = ( data: EmbedProps, - children?: ReactNode[], -): JSX.Element | undefined => createTag("ndlaembed", data, children, { bailOnEmptyData: true }); + children: ReactNode[] | undefined, + key: string | undefined, +): JSX.Element | undefined => createTag("ndlaembed", data, children, { bailOnEmptyData: true }, key); -export const createEmbedTag = (data?: { [key: string]: any }) => { +export const createEmbedTag = (data: { [key: string]: any } | undefined, key: string | undefined) => { if (!data || Object.keys(data).length === 0) { return undefined; } @@ -161,7 +167,7 @@ export const createEmbedTag = (data?: { [key: string]: any }) => { .filter((key) => data[key] !== undefined && !isObject(data[key])) .forEach((key) => (props[`data-${key}`] = data[key])); - return ; + return ; }; export const isUserProvidedEmbedDataValid = (embed: Embed) => { From d01bd56895cc69b298fc39c8cfdb800b9d6e097b Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Tue, 12 Nov 2024 09:29:16 +0100 Subject: [PATCH 008/170] Remove MenuItemButton + use new components in SettingsMenu --- e2e/specs/taxonomy.spec.ts | 2 +- .../folderComponents/SettingsMenu.tsx | 88 ++++++------------- .../SettingsMenuDropdownType.tsx | 51 ++++++----- .../sharedMenuOptions/ConnectExistingNode.tsx | 9 +- .../sharedMenuOptions/CopyRevisionDate.tsx | 70 --------------- .../sharedMenuOptions/DeleteNode.tsx | 10 +-- .../DisconnectFromParent.tsx | 8 +- .../sharedMenuOptions/EditCustomFields.tsx | 18 ++-- .../sharedMenuOptions/EditGrepCodes.tsx | 10 +-- .../sharedMenuOptions/MoveExistingNode.tsx | 9 +- .../sharedMenuOptions/ToNodeDiff.tsx | 29 +++--- .../sharedMenuOptions/ToggleVisibility.tsx | 12 ++- .../components/MenuItemButton.tsx | 34 ------- .../subjectMenuOptions/ChangeNodeName.tsx | 13 ++- .../EditSubjectpageOption.tsx | 31 +++---- .../topicMenuOptions/CopyNodeResources.tsx | 16 ++-- .../PublishChildNodeResources.tsx | 10 +-- .../topicMenuOptions/SetResourcesPrimary.tsx | 8 +- .../topicMenuOptions/SwapTopicArticle.tsx | 10 +-- 19 files changed, 140 insertions(+), 298 deletions(-) delete mode 100644 src/containers/StructurePage/folderComponents/sharedMenuOptions/CopyRevisionDate.tsx delete mode 100644 src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemButton.tsx diff --git a/e2e/specs/taxonomy.spec.ts b/e2e/specs/taxonomy.spec.ts index b4c9ed04f0..87e67d2059 100644 --- a/e2e/specs/taxonomy.spec.ts +++ b/e2e/specs/taxonomy.spec.ts @@ -17,7 +17,7 @@ test.beforeEach(async ({ page }) => { test("should have settingsMenu available after clicking button", async ({ page }) => { await page.getByTestId("structure").getByRole("button", { name: "Engelsk 1" }).click(); await page.getByTestId("settings-button").click(); - expect(await page.getByTestId("settings-menu-modal").count()).toEqual(1); + expect(await page.getByTestId("settings-menu-dialog").count()).toEqual(1); }); test("should be able to change name of node", async ({ page }) => { diff --git a/src/containers/StructurePage/folderComponents/SettingsMenu.tsx b/src/containers/StructurePage/folderComponents/SettingsMenu.tsx index a150ae1087..0d8b4d5eb0 100644 --- a/src/containers/StructurePage/folderComponents/SettingsMenu.tsx +++ b/src/containers/StructurePage/folderComponents/SettingsMenu.tsx @@ -7,32 +7,21 @@ */ import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { Root, Trigger, Close, Content, Portal } from "@radix-ui/react-popover"; -import { animations, colors, spacing, stackOrder } from "@ndla/core"; -import { CloseLine } from "@ndla/icons/action"; import { Settings } from "@ndla/icons/editor"; -import { IconButton } from "@ndla/primitives"; +import { + DialogContent, + DialogHeader, + DialogRoot, + DialogTitle, + DialogTrigger, + IconButton, + DialogBody, +} from "@ndla/primitives"; import { Node } from "@ndla/types-taxonomy"; import SettingsMenuDropdownType from "./SettingsMenuDropdownType"; -import Overlay from "../../../components/Overlay"; -import RoundIcon from "../../../components/RoundIcon"; +import { DialogCloseButton } from "../../../components/DialogCloseButton"; import { getNodeTypeFromNodeId } from "../../../modules/nodes/nodeUtil"; -const TitleWrapper = styled.div` - display: flex; - gap: ${spacing.xsmall}; -`; - -const Header = styled.div` - display: flex; - justify-content: space-between; -`; - -const StyledContent = styled(Content)` - z-index: ${stackOrder.dropdown}; -`; - interface Props { node: Node; rootNodeId: string; @@ -45,8 +34,8 @@ const SettingsMenu = ({ node, rootNodeId, onCurrentNodeChanged, nodeChildren }: const nodeType = getNodeTypeFromNodeId(node.id); return ( - - + + - - - <> - - -
- - } open /> - {t(`taxonomy.${nodeType.toLowerCase()}Settings`)} - - - - - - -
- -
-
- - -
-
+ + + + {t(`taxonomy.${nodeType.toLowerCase()}Settings`)} + + + + + + + ); }; -export const StyledDivWrapper = styled.div` - position: absolute; - ${animations.fadeIn()} - padding: ${spacing.xsmall}; - width: 550px; - background-color: ${colors.brand.greyLightest}; - box-shadow: 0 0 4px 0 rgba(78, 78, 78, 0.5); -`; - export default SettingsMenu; diff --git a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx index 65631333b3..c4fb662acf 100644 --- a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx +++ b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx @@ -7,9 +7,9 @@ */ import { useState } from "react"; +import { styled } from "@ndla/styled-system/jsx"; import { Node } from "@ndla/types-taxonomy"; import ConnectExistingNode from "./sharedMenuOptions/ConnectExistingNode"; -import CopyRevisionDate from "./sharedMenuOptions/CopyRevisionDate"; import DeleteNode from "./sharedMenuOptions/DeleteNode"; import DisconnectFromParent from "./sharedMenuOptions/DisconnectFromParent"; import EditCustomFields from "./sharedMenuOptions/EditCustomFields"; @@ -29,6 +29,18 @@ import { PROGRAMME, SUBJECT_NODE, TOPIC_NODE } from "../../../modules/nodes/node import { getNodeTypeFromNodeId } from "../../../modules/nodes/nodeUtil"; import { useSession } from "../../Session/SessionProvider"; +const ContentWrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "3xsmall", + alignItems: "flex-start", + "& button": { + textAlign: "start", + }, + }, +}); + interface Props { rootNodeId: string; node: Node; @@ -52,7 +64,7 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node if (nodeType === PROGRAMME) { return ( - <> + {isTaxonomyAdmin && } {isTaxonomyAdmin && ( )} - + ); } if (nodeType === SUBJECT_NODE) { if (rootNodeId !== node.id) { return ( - <> + {isTaxonomyAdmin && ( )} - + ); } return ( - <> + {isTaxonomyAdmin && } {isTaxonomyAdmin && ( )} - + ); } if (nodeType === TOPIC_NODE) { return ( - <> + {isTaxonomyAdmin && } {isTaxonomyAdmin && } {isTaxonomyAdmin && ( @@ -141,17 +153,6 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node )} - - {false && } - {isTaxonomyAdmin && ( - - )} )} {isTaxonomyAdmin && } - + + {isTaxonomyAdmin && ( + + )} + ); } return null; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx index 538286c42a..435f3636ff 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx @@ -13,9 +13,8 @@ import { useQueryClient } from "@tanstack/react-query"; import { spacing, colors } from "@ndla/core"; import { AddLine } from "@ndla/icons/action"; import { Done } from "@ndla/icons/editor"; -import { Spinner } from "@ndla/primitives"; +import { Spinner, Button } from "@ndla/primitives"; import { Node, NodeType } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; import NodeSearchDropdown from "./components/NodeSearchDropdown"; import RoundIcon from "../../../../components/RoundIcon"; import { usePostNodeConnectionMutation } from "../../../../modules/nodes/nodeMutations"; @@ -128,12 +127,12 @@ const ConnectExistingNode = ({ editModeHandler: { editMode, toggleEditMode }, cu return ( - - } /> + {loading && ( diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/CopyRevisionDate.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/CopyRevisionDate.tsx deleted file mode 100644 index f371218346..0000000000 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/CopyRevisionDate.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (c) 2022-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import { Time } from "@ndla/icons/common"; -import { Button } from "@ndla/primitives"; -import { Node } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; -import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import { FormActionsContainer } from "../../../../components/FormikForm"; -import Overlay from "../../../../components/Overlay"; -import RoundIcon from "../../../../components/RoundIcon"; -import Spinner from "../../../../components/Spinner"; -import { useCopyRevisionDates } from "../../../../modules/draft/draftMutations"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; -import { StyledErrorMessage } from "../styles"; - -interface Props { - editModeHandler: EditModeHandler; - node: Node; -} - -const CopyRevisionDate = ({ node, editModeHandler: { editMode, toggleEditMode } }: Props) => { - const { t } = useTranslation(); - const { mutateAsync, isPending } = useCopyRevisionDates(); - const [error, setError] = useState(undefined); - - const toggleCopyRevisionDate = () => toggleEditMode("copyRevisionDate"); - - const copyRevisionDate = async () => { - setError(undefined); - toggleCopyRevisionDate(); - await mutateAsync({ nodeId: node.id }, { onError: () => setError(t("taxonomy.copyRevisionDates.error")) }); - }; - - return ( - <> - - } /> - {t("taxonomy.copyRevisionDates.buttonText")} - - - - - - - - {isPending && } - {isPending && } - {error && {error}} - - ); -}; -export default CopyRevisionDate; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx index 4d58573257..e3e1b66a93 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx @@ -11,11 +11,9 @@ import { useLocation, useNavigate } from "react-router-dom"; import { DeleteBinLine } from "@ndla/icons/action"; import { Button } from "@ndla/primitives"; import { Node, NodeChild } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; import { FormActionsContainer } from "../../../../components/FormikForm"; import Overlay from "../../../../components/Overlay"; -import RoundIcon from "../../../../components/RoundIcon"; import Spinner from "../../../../components/Spinner"; import { ARCHIVED } from "../../../../constants"; import { updateStatusDraft } from "../../../../modules/draft/draftApi"; @@ -47,7 +45,7 @@ const DeleteNode = ({ const navigate = useNavigate(); const location = useLocation(); - const disabled = nodeChildren && nodeChildren.length !== 0; + const disabled = nodeChildren.length !== 0; const deleteNodeConnectionMutation = useDeleteNodeConnectionMutation(); const deleteNodeMutation = useDeleteNodeMutation(); @@ -96,10 +94,10 @@ const DeleteNode = ({ }; return ( <> - - } /> + - - } /> + { const { t } = useTranslation(); return ( -
- toggleEditMode("openCustomFields")}> - } /> + <> + {editMode === "openCustomFields" && ( )} -
+ ); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx index f003815702..a7bedebc08 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx @@ -12,11 +12,9 @@ import styled from "@emotion/styled"; import { ButtonV2 } from "@ndla/button"; import { spacing } from "@ndla/core"; import { AddLine, PencilFill, DeleteBinLine } from "@ndla/icons/action"; -import { IconButton, Spinner } from "@ndla/primitives"; +import { IconButton, Spinner, Button } from "@ndla/primitives"; import { Node } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; import MenuItemEditField from "./components/MenuItemEditField"; -import RoundIcon from "../../../../components/RoundIcon"; import { useGrepCodes } from "../../../../modules/grep/grepQueries"; import { useUpdateNodeMetadataMutation } from "../../../../modules/nodes/nodeMutations"; import { getRootIdForNode, isRootNode } from "../../../../modules/nodes/nodeUtil"; @@ -122,10 +120,10 @@ const EditGrepCodes = ({ node, editModeHandler: { editMode, toggleEditMode } }: return ( <> - toggleEditModes()}> - } /> + {editMode === "editGrepCodes" && grepCodesList} ); diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx index 749f1a94e8..7f918726a2 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx @@ -13,9 +13,8 @@ import { useQueryClient } from "@tanstack/react-query"; import { spacing, colors } from "@ndla/core"; import { AddLine } from "@ndla/icons/action"; import { Done } from "@ndla/icons/editor"; -import { Spinner } from "@ndla/primitives"; +import { Spinner, Button } from "@ndla/primitives"; import { Node, NodeType } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; import NodeSearchDropdown from "./components/NodeSearchDropdown"; import RoundIcon from "../../../../components/RoundIcon"; import { fetchConnectionsForNode } from "../../../../modules/nodes/nodeApi"; @@ -149,12 +148,12 @@ const MoveExistingNode = ({ return ( - - } /> + {loading && ( diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToNodeDiff.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToNodeDiff.tsx index 7b2ab353bd..afda8882d1 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToNodeDiff.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToNodeDiff.tsx @@ -7,13 +7,9 @@ */ import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import styled from "@emotion/styled"; -import { colors } from "@ndla/core"; -import { Taxonomy } from "@ndla/icons/editor"; +import { ExternalLinkLine } from "@ndla/icons/common"; +import { SafeLinkButton } from "@ndla/safelink"; import { Node } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; -import RoundIcon from "../../../../components/RoundIcon"; import { useTaxonomyVersion } from "../../../../containers/StructureVersion/TaxonomyVersionProvider"; import { toNodeDiff } from "../../../../util/routeHelpers"; @@ -21,22 +17,19 @@ interface Props { node: Node; } -const StyledLink = styled(Link)` - color: ${colors.brand.greyDark}; - &hover { - color: ${colors.brand.primary}; - } -`; const ToNodeDiff = ({ node }: Props) => { const { t } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); return ( - - - } /> - {t("diff.compareVersions")} - - + + {t("diff.compareVersions")} + + ); }; export default ToNodeDiff; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToggleVisibility.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToggleVisibility.tsx index 2315287108..cc8d6229b3 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToggleVisibility.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ToggleVisibility.tsx @@ -9,12 +9,10 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; -import { Eye } from "@ndla/icons/editor"; -import { SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; +import { EyeFill } from "@ndla/icons/editor"; +import { Button, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeType } from "@ndla/types-taxonomy"; -import MenuItemButton from "./components/MenuItemButton"; -import RoundIcon from "../../../../components/RoundIcon"; import { useUpdateNodeMetadataMutation } from "../../../../modules/nodes/nodeMutations"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; @@ -71,10 +69,10 @@ const ToggleVisibility = ({ return ( <> - - } /> + {editMode === "toggleMetadataVisibility" && ( diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemButton.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemButton.tsx deleted file mode 100644 index 4b4e6d832e..0000000000 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemButton.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2016-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { forwardRef, ReactNode } from "react"; -import styled from "@emotion/styled"; -import { ButtonV2 } from "@ndla/button"; -import { spacing } from "@ndla/core"; - -const StyledMenuItemButton = styled(ButtonV2)` - display: flex; - align-items: center; - margin: 0 ${spacing.xxsmall}; -`; - -interface Props { - children: ReactNode; - "data-testid"?: string; - onClick?: () => void; - disabled?: boolean; - title?: string; -} - -const MenuItemButton = forwardRef(({ children, ...rest }, ref) => ( - - {children} - -)); - -export default MenuItemButton; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx index e0327c8395..815c0877e8 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx @@ -11,7 +11,7 @@ import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { Portal } from "@ark-ui/react"; import { useQueryClient } from "@tanstack/react-query"; -import { PencilFill, DeleteBinLine } from "@ndla/icons/action"; +import { DeleteBinLine, PencilFill } from "@ndla/icons/action"; import { Button, DialogBody, @@ -35,7 +35,6 @@ import { DialogCloseButton } from "../../../../components/DialogCloseButton"; import { FormField } from "../../../../components/FormField"; import { FormActionsContainer, FormikForm } from "../../../../components/FormikForm"; import validateFormik, { RulesType } from "../../../../components/formikValidationSchema"; -import RoundIcon from "../../../../components/RoundIcon"; import SaveButton from "../../../../components/SaveButton"; import Spinner from "../../../../components/Spinner"; import { subjectpageLanguages } from "../../../../i18n2"; @@ -49,7 +48,6 @@ import { isFormikFormDirty } from "../../../../util/formHelper"; import handleError from "../../../../util/handleError"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import { EditModeHandler } from "../SettingsMenuDropdownType"; -import MenuItemButton from "../sharedMenuOptions/components/MenuItemButton"; import { StyledErrorMessage } from "../styles"; const InputWrapper = styled("div", { @@ -92,12 +90,11 @@ const ChangeNodeName = ({ editModeHandler: { editMode, toggleEditMode }, node }: return ( onModalChange(details.open)}> - {/* TODO: Remove consumeCss once MenuItemButton is updated */} - - - } /> + + diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/EditSubjectpageOption.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/EditSubjectpageOption.tsx index 3466a8d1a4..a648d2544e 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/EditSubjectpageOption.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/EditSubjectpageOption.tsx @@ -7,28 +7,17 @@ */ import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import styled from "@emotion/styled"; -import { colors } from "@ndla/core"; -import { Home } from "@ndla/icons/common"; +import { ExternalLinkLine } from "@ndla/icons/common"; +import { SafeLinkButton } from "@ndla/safelink"; import { Node } from "@ndla/types-taxonomy"; -import RoundIcon from "../../../../components/RoundIcon"; import { toCreateSubjectpage, toEditSubjectpage } from "../../../../util/routeHelpers"; import { getIdFromUrn } from "../../../../util/subjectHelpers"; -import MenuItemButton from "../sharedMenuOptions/components/MenuItemButton"; interface Props { node: Node; } -const StyledLink = styled(Link)` - color: ${colors.brand.greyDark}; - &:hover { - color: ${colors.brand.primary}; - } -`; - const EditSubjectpageOption = ({ node }: Props) => { const { t, i18n } = useTranslation(); @@ -37,12 +26,16 @@ const EditSubjectpageOption = ({ node }: Props) => { : toCreateSubjectpage(node.id, i18n.language); return ( - - - } /> - {t("taxonomy.editSubjectpage")} - - + + {t("taxonomy.editSubjectpage")} + + ); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx index be22e9a06c..beb6ebc491 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx @@ -11,9 +11,9 @@ import { useTranslation } from "react-i18next"; import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; import { spacing, colors } from "@ndla/core"; -import { Copy } from "@ndla/icons/action"; +import { Copy, FileCopyLine } from "@ndla/icons/action"; import { Done } from "@ndla/icons/editor"; -import { Spinner } from "@ndla/primitives"; +import { Spinner, Button } from "@ndla/primitives"; import { Node, NodeChild, NodeType } from "@ndla/types-taxonomy"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; import RoundIcon from "../../../../components/RoundIcon"; @@ -25,7 +25,6 @@ import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; import { EditModeHandler } from "../SettingsMenuDropdownType"; -import MenuItemButton from "../sharedMenuOptions/components/MenuItemButton"; import NodeSearchDropdown from "../sharedMenuOptions/components/NodeSearchDropdown"; type ActionType = Extract; @@ -40,11 +39,6 @@ const StyledSpinner = styled(Spinner)` margin: 0px 4px; `; -const StyledCopyIcon = styled(Copy)` - width: 8px; - height: 8px; -`; - const Wrapper = styled.div` display: flex; align-items: center; @@ -204,10 +198,10 @@ const CopyNodeResources = ({ editModeHandler: { editMode, toggleEditMode }, curr return ( <> - - } /> + {showDisplay && ( {done ? : } diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx index 6a2bbeaa8c..2e67a25b11 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx @@ -12,14 +12,13 @@ import { useTranslation } from "react-i18next"; import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; import { colors } from "@ndla/core"; -import { Done } from "@ndla/icons/editor"; +import { CheckLine, Done } from "@ndla/icons/editor"; import { Button, Spinner } from "@ndla/primitives"; import { IArticle } from "@ndla/types-backend/draft-api"; import { ILearningPathV2 } from "@ndla/types-backend/learningpath-api"; import { Node } from "@ndla/types-taxonomy"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; import { FormActionsContainer } from "../../../../components/FormikForm"; -import RoundIcon from "../../../../components/RoundIcon"; import { PUBLISHED } from "../../../../constants"; import { fetchDrafts, updateStatusDraft } from "../../../../modules/draft/draftApi"; import { fetchLearningpaths, updateStatusLearningpath } from "../../../../modules/learningpath/learningpathApi"; @@ -27,7 +26,6 @@ import { fetchNodeResources } from "../../../../modules/nodes/nodeApi"; import { RESOURCE_META } from "../../../../queryKeys"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; -import MenuItemButton from "../sharedMenuOptions/components/MenuItemButton"; interface Props { node: Node; @@ -146,10 +144,10 @@ const PublishChildNodeResources = ({ node }: Props) => { return ( <> - setShowConfirmation(true)}> - } /> + {showDisplay && ( {done ? : } diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx index 73cd9f5eb2..d33da88c76 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx @@ -14,12 +14,10 @@ import { Node } from "@ndla/types-taxonomy"; import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; import { FormActionsContainer } from "../../../../components/FormikForm"; import Overlay from "../../../../components/Overlay"; -import RoundIcon from "../../../../components/RoundIcon"; import Spinner from "../../../../components/Spinner"; import { usePutResourcesPrimaryMutation } from "../../../../modules/nodes/nodeMutations"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import { EditModeHandler } from "../SettingsMenuDropdownType"; -import MenuItemButton from "../sharedMenuOptions/components/MenuItemButton"; import { StyledErrorMessage } from "../styles"; interface Props { @@ -48,10 +46,10 @@ const SetResourcesPrimary = ({ node, recursive = false, editModeHandler: { editM return ( <> - - } /> + - - } /> + {putNodeMutation.isPending && ( From 81f6d82b15240b6fc957de5f20aed08fff29e71d Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Wed, 13 Nov 2024 15:52:42 +0100 Subject: [PATCH 009/170] Big rewrite + cleanup of SettingsMenu --- e2e/specs/taxonomy.spec.ts | 4 +- src/components/FormWrapper.tsx | 8 +- src/components/Overlay.tsx | 65 ---- src/components/RoundIcon.tsx | 78 ----- .../folderComponents/SettingsMenu.tsx | 11 +- .../SettingsMenuDropdownType.tsx | 318 +++++++++++------- .../sharedMenuOptions/ConnectExistingNode.tsx | 133 +++----- .../sharedMenuOptions/DeleteNode.tsx | 75 ++--- .../DisconnectFromParent.tsx | 64 ++-- .../sharedMenuOptions/EditCustomFields.tsx | 44 --- .../sharedMenuOptions/EditGrepCodes.tsx | 101 +----- .../sharedMenuOptions/MoveExistingNode.tsx | 143 +++----- .../sharedMenuOptions/ToggleVisibility.tsx | 65 ++-- .../components/ConstantMetaField.tsx | 95 +++--- .../components/CustomFieldComponent.tsx | 81 ++--- .../components/MenuItemCustomField.tsx | 107 +++--- .../components/MenuItemEditField.tsx | 103 ------ .../StructurePage/folderComponents/styles.ts | 27 -- .../subjectMenuOptions/AddNodeTranslation.tsx | 7 +- .../subjectMenuOptions/ChangeNodeName.tsx | 288 +++++++--------- .../TaxonomyMetadataDropdown.tsx | 76 ++--- .../ToggleExplanationSubject.tsx | 29 +- .../ToggleProgrammeSubject.tsx | 25 +- .../topicMenuOptions/CopyNodeResources.tsx | 179 +++++----- .../topicMenuOptions/GroupTopicResources.tsx | 31 +- .../PublishChildNodeResources.tsx | 151 ++++----- .../topicMenuOptions/SetResourcesPrimary.tsx | 70 ++-- .../topicMenuOptions/SwapTopicArticle.tsx | 153 ++++----- .../resourceComponents/GrepCodesForm.tsx | 12 +- .../resourceComponents/ResourceItems.tsx | 4 +- src/interfaces.ts | 21 -- src/phrases/phrases-en.ts | 2 + src/phrases/phrases-nb.ts | 2 + src/phrases/phrases-nn.ts | 2 + 34 files changed, 985 insertions(+), 1589 deletions(-) delete mode 100644 src/components/Overlay.tsx delete mode 100644 src/components/RoundIcon.tsx delete mode 100644 src/containers/StructurePage/folderComponents/sharedMenuOptions/EditCustomFields.tsx delete mode 100644 src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemEditField.tsx delete mode 100644 src/containers/StructurePage/folderComponents/styles.ts diff --git a/e2e/specs/taxonomy.spec.ts b/e2e/specs/taxonomy.spec.ts index 87e67d2059..69573f8a36 100644 --- a/e2e/specs/taxonomy.spec.ts +++ b/e2e/specs/taxonomy.spec.ts @@ -42,8 +42,8 @@ test("should be able to change visibility", async ({ page }) => { await page.getByTestId("structure").getByRole("button", { name: "Engelsk 1" }).click(); await page.getByTestId("settings-button").click(); await page.getByTestId("toggleVisibilityButton").click(); - expect(await page.getByLabel("Synlig").count()).toEqual(1); - expect(await page.getByLabel("Synlig").isChecked()).toBeTruthy(); + expect(await page.getByLabel("Synlig", { exact: true }).count()).toEqual(1); + expect(await page.getByLabel("Synlig", { exact: true }).isChecked()).toBeTruthy(); }); test("can toggle favourites", async ({ page }) => { diff --git a/src/components/FormWrapper.tsx b/src/components/FormWrapper.tsx index 098be899b5..5f7b2df9a1 100644 --- a/src/components/FormWrapper.tsx +++ b/src/components/FormWrapper.tsx @@ -6,11 +6,11 @@ * */ -import { ReactNode } from "react"; +import { ReactNode, ComponentPropsWithRef } from "react"; import { styled } from "@ndla/styled-system/jsx"; import { Form } from "./FormikForm"; -interface Props { +interface Props extends ComponentPropsWithRef<"form"> { inModal?: boolean; children: ReactNode; } @@ -21,11 +21,11 @@ const StyledForm = styled(Form, { }, }); -const FormWrapper = ({ inModal, children }: Props) => { +const FormWrapper = ({ inModal, children, ...rest }: Props) => { if (inModal) { return {children}; } - return
{children}
; + return
{children}
; }; export default FormWrapper; diff --git a/src/components/Overlay.tsx b/src/components/Overlay.tsx deleted file mode 100644 index 31406bdd8a..0000000000 --- a/src/components/Overlay.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2017-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { MouseEvent } from "react"; -import { css, SerializedStyles } from "@emotion/react"; -import styled from "@emotion/styled"; -import { animations, stackOrder } from "@ndla/core"; - -const appearances: Record = { - zIndex: css` - z-index: ${stackOrder.dropdown - stackOrder.offsetSingle}; - `, - absolute: css` - position: absolute; - width: 100%; - height: 100%; - `, - "white-opacity": css` - opacity: 0.8; - background-color: white; - `, - lighter: css` - background: rgba(1, 1, 1, 0.3); - z-index: ${stackOrder.offsetDouble}; - `, -}; - -const getAllAppearances = (modifiers: string | string[]) => { - if (Array.isArray(modifiers)) { - return modifiers.map((modifier) => appearances[modifier]); - } - return appearances[modifiers]; -}; - -const StyledOverlay = styled.div<{ modifiers: string | string[] }>` - position: fixed; - top: 0; - left: 0; - height: 100vh; - width: 100vw; - z-index: ${stackOrder.offsetDouble}; - background: rgba(0, 0, 0, 0.3); - - ${animations.fadeIn()} - ${(p) => getAllAppearances(p.modifiers)} -`; - -interface Props { - onExit?: (event: MouseEvent) => void; - modifiers?: string | string[]; -} - -const Overlay = ({ onExit, modifiers = "" }: Props) => - onExit ? ( -
); diff --git a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx index c4fb662acf..71e5f44dcf 100644 --- a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx +++ b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx @@ -6,13 +6,14 @@ * */ -import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { Node } from "@ndla/types-taxonomy"; +import MenuItemCustomField from "./sharedMenuOptions/components/MenuItemCustomField"; import ConnectExistingNode from "./sharedMenuOptions/ConnectExistingNode"; import DeleteNode from "./sharedMenuOptions/DeleteNode"; import DisconnectFromParent from "./sharedMenuOptions/DisconnectFromParent"; -import EditCustomFields from "./sharedMenuOptions/EditCustomFields"; import EditGrepCodes from "./sharedMenuOptions/EditGrepCodes"; import MoveExistingNode from "./sharedMenuOptions/MoveExistingNode"; import ToggleVisibility from "./sharedMenuOptions/ToggleVisibility"; @@ -24,18 +25,21 @@ import PublishChildNodeResources from "./topicMenuOptions/PublishChildNodeResour import SetResourcesPrimary from "./topicMenuOptions/SetResourcesPrimary"; import SwapTopicArticle from "./topicMenuOptions/SwapTopicArticle"; import { TAXONOMY_ADMIN_SCOPE } from "../../../constants"; -import { EditMode } from "../../../interfaces"; import { PROGRAMME, SUBJECT_NODE, TOPIC_NODE } from "../../../modules/nodes/nodeApiTypes"; import { getNodeTypeFromNodeId } from "../../../modules/nodes/nodeUtil"; import { useSession } from "../../Session/SessionProvider"; -const ContentWrapper = styled("div", { +const StyledTabsContent = styled(TabsContent, { base: { - display: "flex", - flexDirection: "column", - gap: "3xsmall", - alignItems: "flex-start", - "& button": { + width: "100%", + }, +}); + +const StyledTabsList = styled(TabsList, { + base: { + maxWidth: "surface.xxsmall", + "& > button": { + whiteSpace: "unset", textAlign: "start", }, }, @@ -48,137 +52,225 @@ interface Props { onCurrentNodeChanged: (node?: Node) => void; } -export interface EditModeHandler { - editMode: EditMode; - toggleEditMode: (editMode: EditMode) => void; -} - const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, nodeChildren }: Props) => { + const { t } = useTranslation(); const { userPermissions } = useSession(); - const [editMode, setEditMode] = useState(""); const nodeType = getNodeTypeFromNodeId(node.id); - const toggleEditMode = (mode: EditMode) => setEditMode((prev) => (mode === prev ? "" : mode)); - const editModeHandler = { editMode, toggleEditMode }; const isTaxonomyAdmin = userPermissions?.includes(TAXONOMY_ADMIN_SCOPE); if (nodeType === PROGRAMME) { return ( - - {isTaxonomyAdmin && } - {isTaxonomyAdmin && ( - - )} - - - + <> + + + {isTaxonomyAdmin && ( + {t("taxonomy.changeName.buttonTitle")} + )} + {isTaxonomyAdmin && ( + {t("taxonomy.metadata.customFields.alterFields")} + )} + + {t("taxonomy.addExistingNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} + + + {t("taxonomy.connectExistingNode", { + nodeType: t("taxonomy.nodeType.SUBJECT"), + })} + + {t("metadata.changeVisibility")} + {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + + + + + + + + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && } - {isTaxonomyAdmin && ( - - )} - + ); } if (nodeType === SUBJECT_NODE) { if (rootNodeId !== node.id) { return ( - + + + {isTaxonomyAdmin && {t("taxonomy.disconnectNode")}} + + {isTaxonomyAdmin && ( - + + + )} - + ); } return ( - - {isTaxonomyAdmin && } - {isTaxonomyAdmin && ( - - )} - - - {isTaxonomyAdmin && } + <> + + + {isTaxonomyAdmin && ( + + {t("taxonomy.changeName.buttonTitle")} + + )} + {isTaxonomyAdmin && ( + {t("taxonomy.metadata.customFields.alterFields")} + )} + + {t("taxonomy.addExistingNode", { + nodeType: t(`taxonomy.nodeType.TOPIC`), + })} + + + {t("metadata.changeVisibility")} + + {isTaxonomyAdmin && {t("taxonomy.grepCodes.edit")}} + {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + + + + + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && } - {isTaxonomyAdmin && ( - - )} - + ); } if (nodeType === TOPIC_NODE) { return ( - - {isTaxonomyAdmin && } - {isTaxonomyAdmin && } - {isTaxonomyAdmin && ( - - )} - - - - {isTaxonomyAdmin && ( - - )} - {isTaxonomyAdmin && } + <> + + + {isTaxonomyAdmin && {t("taxonomy.publish.button")}} + {isTaxonomyAdmin && ( + {t("taxonomy.swapTopicArticle.info")} + )} + {isTaxonomyAdmin && ( + {t("taxonomy.metadata.customFields.alterFields")} + )} + + {t("taxonomy.addExistingNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} + + {t("metadata.changeVisibility")} + {t("taxonomy.copyResources.info")} + {isTaxonomyAdmin && {t("taxonomy.cloneResources.info")}} + {isTaxonomyAdmin && ( + + {t("taxonomy.resourcesPrimary.recursiveButtonText")} + + )} + {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + + + + + + + + + + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + {isTaxonomyAdmin && ( + + + + )} + - {isTaxonomyAdmin && ( - - )} - + ); } return null; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx index 435f3636ff..97d14faa33 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx @@ -6,62 +6,44 @@ * */ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; -import { spacing, colors } from "@ndla/core"; -import { AddLine } from "@ndla/icons/action"; -import { Done } from "@ndla/icons/editor"; -import { Spinner, Button } from "@ndla/primitives"; +import { CheckLine } from "@ndla/icons/editor"; +import { Text, Spinner } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeType } from "@ndla/types-taxonomy"; import NodeSearchDropdown from "./components/NodeSearchDropdown"; -import RoundIcon from "../../../../components/RoundIcon"; import { usePostNodeConnectionMutation } from "../../../../modules/nodes/nodeMutations"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; interface Props { - editModeHandler: EditModeHandler; currentNode: Node; nodeType: NodeType; } -const StyledSuccessIcon = styled(Done)` - border-radius: 90px; - margin: 5px; - background-color: green; - color: white; -`; +const StatusIndicatorContent = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + }, +}); -const Wrapper = styled.div` - display: flex; - align-items: center; - margin: ${spacing.xsmall}; -`; +const Wrapper = styled("div", { + base: { + width: "100%", + display: "flex", + flexDirection: "column", + gap: "3xsmall", + }, +}); -const MenuContent = styled.div` - display: flex; - flex-direction: row; - align-items: center; -`; +const StyledCheckLine = styled(CheckLine, { + base: { fill: "stroke.success" }, +}); -const StyledMenuWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: baseline; -`; - -const StyledErrorMessage = styled.div` - color: ${colors.support.red}; -`; - -const StyledActionContent = styled.div` - padding-left: ${spacing.normal}; -`; - -const ConnectExistingNode = ({ editModeHandler: { editMode, toggleEditMode }, currentNode, nodeType }: Props) => { +const ConnectExistingNode = ({ currentNode, nodeType }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); const { mutateAsync: connectNode } = usePostNodeConnectionMutation(); @@ -70,18 +52,9 @@ const ConnectExistingNode = ({ editModeHandler: { editMode, toggleEditMode }, cu const [success, setSuccess] = useState(false); const qc = useQueryClient(); - useEffect(() => { - if (success && editMode === "connectExistingNode") { - setSuccess(false); - } - }, [editMode, success]); - - const toggleEditModeFunc = () => toggleEditMode("connectExistingNode"); - const handleSubmit = async (node: Node) => { setLoading(true); setError(undefined); - toggleEditModeFunc(); await connectNode( { taxonomyVersion, @@ -103,52 +76,38 @@ const ConnectExistingNode = ({ editModeHandler: { editMode, toggleEditMode }, cu ); }; - if (editMode === "connectExistingNode") { - return ( - - } /> - { - return !node.paths?.some((p) => { - const split = p.replace("/", "").split("/"); - return split[split.length - 2] === currentNode.id.replace("urn:", ""); - }); - }} - /> - - ); - } - return ( - - - - - - - - - {loading && } - {loading && } - {error && {error}} - + + +

{t("taxonomy.deleteNode")}

+
+ + + {t("taxonomy.confirmDelete")} + + + {t("alertModal.delete")} + + {error && {error}} +
); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx index 9ef517ef1e..f2a6cbcc37 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx @@ -10,26 +10,29 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { useQueryClient } from "@tanstack/react-query"; -import { DeleteBinLine } from "@ndla/icons/action"; -import { Button } from "@ndla/primitives"; +import { ErrorWarningLine } from "@ndla/icons/common"; +import { Button, Heading, MessageBox, Text } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeChild } from "@ndla/types-taxonomy"; -import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; import { FormActionsContainer } from "../../../../components/FormikForm"; -import Overlay from "../../../../components/Overlay"; -import Spinner from "../../../../components/Spinner"; import { useDeleteNodeConnectionMutation } from "../../../../modules/nodes/nodeMutations"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; -import { StyledErrorMessage } from "../styles"; + +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "small", + }, +}); interface Props { node: Node | NodeChild; - editModeHandler: EditModeHandler; onCurrentNodeChanged: (node?: Node) => void; } -const DisconnectFromParent = ({ node, editModeHandler: { editMode, toggleEditMode }, onCurrentNodeChanged }: Props) => { +const DisconnectFromParent = ({ node, onCurrentNodeChanged }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); const { mutateAsync: disconnectNode } = useDeleteNodeConnectionMutation(); @@ -39,12 +42,9 @@ const DisconnectFromParent = ({ node, editModeHandler: { editMode, toggleEditMod const location = useLocation(); const qc = useQueryClient(); - const toggleDisconnect = () => toggleEditMode("disconnectFromParent"); - const onDisconnect = async (): Promise => { setLoading(true); setError(undefined); - toggleDisconnect(); if ("connectionId" in node) { await disconnectNode( { @@ -69,31 +69,21 @@ const DisconnectFromParent = ({ node, editModeHandler: { editMode, toggleEditMod }; return ( - <> - - - - - - - - {loading && } - {loading && } - {error && {error}} - + + +

{t("taxonomy.disconnectNode")}

+
+ + + {t("taxonomy.publish.info")} + + + + + {error && {error}} +
); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditCustomFields.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditCustomFields.tsx deleted file mode 100644 index becc2bdfe4..0000000000 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditCustomFields.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2021-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { useTranslation } from "react-i18next"; -import { PencilFill } from "@ndla/icons/action"; -import { Button } from "@ndla/primitives"; -import { Node } from "@ndla/types-taxonomy"; -import MenuItemCustomField from "./components/MenuItemCustomField"; -import { EditMode } from "../../../../interfaces"; - -interface Props { - node: Node; - toggleEditMode: (state: EditMode) => void; - editMode: string; - onCurrentNodeChanged: (node: Node) => void; -} - -const EditCustomFields = ({ node, toggleEditMode, editMode, onCurrentNodeChanged }: Props) => { - const { t } = useTranslation(); - return ( - <> - - - {editMode === "openCustomFields" && ( - - )} - - ); -}; - -export default EditCustomFields; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx index a7bedebc08..07cf90dfe6 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/EditGrepCodes.tsx @@ -6,48 +6,21 @@ * */ -import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { ButtonV2 } from "@ndla/button"; -import { spacing } from "@ndla/core"; -import { AddLine, PencilFill, DeleteBinLine } from "@ndla/icons/action"; -import { IconButton, Spinner, Button } from "@ndla/primitives"; import { Node } from "@ndla/types-taxonomy"; -import MenuItemEditField from "./components/MenuItemEditField"; -import { useGrepCodes } from "../../../../modules/grep/grepQueries"; import { useUpdateNodeMetadataMutation } from "../../../../modules/nodes/nodeMutations"; import { getRootIdForNode, isRootNode } from "../../../../modules/nodes/nodeUtil"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; +import GrepCodesForm from "../../resourceComponents/GrepCodesForm"; interface Props { - editModeHandler: EditModeHandler; node: Node; } -export const DropDownWrapper = styled("div")` - font-size: 0.9rem; - background-color: white; - padding: calc(${spacing.small} / 2); -`; - -const StyledGrepItem = styled("div")` - display: flex; - align-items: center; - justify-content: space-between; - margin: calc(var(--spacing--small) / 2); -`; - -const EditGrepCodes = ({ node, editModeHandler: { editMode, toggleEditMode } }: Props) => { +const EditGrepCodes = ({ node }: Props) => { const rootId = getRootIdForNode(node); - const { t } = useTranslation(); const { id, metadata } = node; - const [grepCodes, setGrepCodes] = useState(metadata?.grepCodes ?? []); - const [addingNewGrepCode, setAddingNewGrepCode] = useState(false); const { taxonomyVersion } = useTaxonomyVersion(); const { mutateAsync: patchMetadata } = useUpdateNodeMetadataMutation(); - const grepCodesWithName = useGrepCodes(grepCodes, editMode === "editGrepCodes"); const updateMetadata = async (codes: string[]) => { await patchMetadata({ @@ -56,77 +29,9 @@ const EditGrepCodes = ({ node, editModeHandler: { editMode, toggleEditMode } }: rootId: isRootNode(node) ? undefined : rootId, taxonomyVersion, }); - setGrepCodes(codes); }; - const toggleEditModes = () => toggleEditMode("editGrepCodes"); - - const addGrepCode = async (code: string) => updateMetadata([...grepCodes, code.toUpperCase()]); - - const deleteGrepCode = (code: string) => updateMetadata(grepCodes.filter((c) => c !== code)); - - const grepCodesList = ( - - {grepCodesWithName?.length > 0 ? ( - grepCodesWithName.map((grepCode, index) => { - if (grepCode.isLoading) { - return ; - } - if (!grepCode.data) { - return null; - } - return ( - - {grepCode.data.title} - deleteGrepCode(grepCode.data.code)} - > - - - - ); - }) - ) : ( -

{t("taxonomy.grepCodes.empty")}

- )} - - {addingNewGrepCode ? ( - setAddingNewGrepCode(!addingNewGrepCode)} - onSubmit={addGrepCode} - icon={} - placeholder={t("form.grepCodes.placeholder")} - /> - ) : ( - setAddingNewGrepCode(!addingNewGrepCode)}> - - {t("taxonomy.grepCodes.addNew")} - - )} -
- ); - - return ( - <> - - {editMode === "editGrepCodes" && grepCodesList} - - ); + return ; }; export default EditGrepCodes; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx index 7f918726a2..cd8a50cad8 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/MoveExistingNode.tsx @@ -6,17 +6,14 @@ * */ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; -import { spacing, colors } from "@ndla/core"; -import { AddLine } from "@ndla/icons/action"; -import { Done } from "@ndla/icons/editor"; -import { Spinner, Button } from "@ndla/primitives"; +import { CheckLine } from "@ndla/icons/editor"; +import { Text, Spinner } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeType } from "@ndla/types-taxonomy"; import NodeSearchDropdown from "./components/NodeSearchDropdown"; -import RoundIcon from "../../../../components/RoundIcon"; import { fetchConnectionsForNode } from "../../../../modules/nodes/nodeApi"; import { useDeleteNodeConnectionMutation, @@ -24,52 +21,39 @@ import { } from "../../../../modules/nodes/nodeMutations"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; + +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "3xsmall", + width: "100%", + }, +}); + +const StyledCheckLine = styled(CheckLine, { + base: { + fill: "stroke.success", + }, +}); + +const MenuContent = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + }, +}); + +const StyledMenuWrapper = styled("div", { + base: { display: "flex" }, +}); interface Props { - editModeHandler: EditModeHandler; currentNode: Node; nodeType?: NodeType; } -const StyledSuccessIcon = styled(Done)` - border-radius: 90px; - margin: 5px; - background-color: green; - color: white; -`; - -const Wrapper = styled.div` - display: flex; - align-items: center; - margin: ${spacing.xsmall}; -`; - -const MenuContent = styled.div` - display: flex; - flex-direction: row; - align-items: center; -`; - -const StyledMenuWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: baseline; -`; - -const StyledErrorMessage = styled.div` - color: ${colors.support.red}; -`; - -const StyledActionContent = styled.div` - padding-left: ${spacing.normal}; -`; - -const MoveExistingNode = ({ - editModeHandler: { editMode, toggleEditMode }, - currentNode, - nodeType = "TOPIC", -}: Props) => { +const MoveExistingNode = ({ currentNode, nodeType = "TOPIC" }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); const deleteNodeConnectionMutation = useDeleteNodeConnectionMutation(); @@ -79,18 +63,9 @@ const MoveExistingNode = ({ const [success, setSuccess] = useState(false); const qc = useQueryClient(); - useEffect(() => { - if (success && editMode === "moveExistingNode") { - setSuccess(false); - } - }, [editMode, success]); - - const toggleEditModeFunc = () => toggleEditMode("moveExistingNode"); - const handleSubmit = async (node: Node) => { setLoading(true); setError(undefined); - toggleEditModeFunc(); try { // drop all parent connections and replace with this. const connections = await fetchConnectionsForNode({ @@ -124,52 +99,38 @@ const MoveExistingNode = ({ } }; - if (editMode === "moveExistingNode") { - return ( - - } /> - { - return !node.paths?.some((p) => { - const split = p.replace("/", "").split("/"); - return split[split.length - 2] === currentNode.id.replace("urn:", ""); - }); - }} - /> - - ); - } - return ( - - - {editMode === "toggleMetadataVisibility" && ( - - - {t("metadata.visible")} - - - - - - - )} + + +

{t("metadata.changeVisibility")}

+
+ {isPending && } +
+ + {t("metadata.visible")} + + + + + ); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx index 5e390c76b9..fb2a106a87 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx @@ -7,42 +7,50 @@ */ import { useState, KeyboardEvent } from "react"; -import styled from "@emotion/styled"; -import { spacing } from "@ndla/core"; +import { useTranslation } from "react-i18next"; +import { FieldLabel } from "@ark-ui/react"; import { DeleteBinLine } from "@ndla/icons/action"; -import { Done } from "@ndla/icons/editor"; +import { CheckLine } from "@ndla/icons/editor"; +import { FieldInput, FieldRoot, IconButton, Input } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Metadata } from "@ndla/types-taxonomy"; -import CustomFieldButton from "./CustomFieldButton"; -import RoundIcon from "../../../../../components/RoundIcon"; -import { StyledMenuItemEditField, StyledMenuItemInputField } from "../../styles"; +import { TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID } from "../../../../../constants"; + +const Wrapper = styled("div", { + base: { + display: "flex", + width: "100%", + alignItems: "flex-end", + gap: "3xsmall", + }, +}); + +const StyledFieldRoot = styled(FieldRoot, { + base: { + width: "100%", + }, +}); + +const ButtonsWrapper = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + }, +}); interface Props { - fieldKey: string; onSubmit: Function; initialVal?: string; - keyPlaceholder?: string; - valuePlaceholder?: string; - dataTestid?: string; } -const StyledCustomFieldButton = styled(CustomFieldButton)` - margin-left: ${spacing.xxsmall}; -`; - -const ConstantMetaField = ({ - onSubmit, - keyPlaceholder, - valuePlaceholder, - initialVal = "", - dataTestid, - fieldKey, -}: Props) => { +const ConstantMetaField = ({ onSubmit, initialVal = "" }: Props) => { + const { t } = useTranslation(); const [currentVal, setCurrentVal] = useState(); const handleSubmit = () => { const newPair: Record = {}; if (initialVal !== currentVal && !!currentVal) { - newPair[fieldKey] = currentVal; + newPair[TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID] = currentVal; onSubmit((prevState: Metadata["customFields"]) => ({ ...prevState, ...newPair, @@ -52,7 +60,7 @@ const ConstantMetaField = ({ const handleDelete = () => { onSubmit((prevState: Metadata["customFields"]) => { - delete prevState[fieldKey]; + delete prevState[TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID]; return { ...prevState }; }); setCurrentVal(""); @@ -65,24 +73,27 @@ const ConstantMetaField = ({ }; return ( - - - - setCurrentVal(e.target.value)} - onKeyDown={handleKeyPress} - /> - - - - - - - + + + {t("taxonomy.metadata.customFields.oldSubjectId")} + setCurrentVal(e.target.value)} + onKeyDown={handleKeyPress} + componentSize="small" + /> + + + + + + + + + + ); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldComponent.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldComponent.tsx index 969b128998..46464f3417 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldComponent.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldComponent.tsx @@ -7,36 +7,25 @@ */ import { useState, KeyboardEvent } from "react"; -import styled from "@emotion/styled"; -import { spacing } from "@ndla/core"; +import { useTranslation } from "react-i18next"; import { DeleteBinLine } from "@ndla/icons/action"; -import { Done } from "@ndla/icons/editor"; +import { CheckLine } from "@ndla/icons/editor"; +import { IconButton, Input } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Metadata } from "@ndla/types-taxonomy"; -import CustomFieldButton from "./CustomFieldButton"; -import RoundIcon from "../../../../../components/RoundIcon"; -import { StyledMenuItemEditField, StyledMenuItemInputField } from "../../styles"; +const ContentWrapper = styled("div", { + base: { display: "flex", gap: "3xsmall" }, +}); interface Props { onSubmit: (prevState: any) => void; onClose?: () => void; initialKey?: string; initialVal?: string; - dataTestid?: string; - placeholder?: string; } -const StyledCustomFieldButton = styled(CustomFieldButton)` - margin-left: ${spacing.xxsmall}; -`; - -const CustomFieldComponent = ({ - onSubmit, - onClose, - initialKey = "", - initialVal = "", - dataTestid = "customFieldComponent", - placeholder, -}: Props) => { +const CustomFieldComponent = ({ onSubmit, onClose, initialKey = "", initialVal = "" }: Props) => { + const { t } = useTranslation(); const [currentKey, setCurrentKey] = useState(undefined); const [currentVal, setCurrentVal] = useState(undefined); @@ -75,35 +64,31 @@ const CustomFieldComponent = ({ handleSubmit(); } }; - return ( - <> - - - setCurrentKey(e.target.value)} - onKeyDown={handleKeyPress} - /> - setCurrentVal(e.target.value)} - onKeyDown={handleKeyPress} - /> - - - - - - - - + + setCurrentKey(e.target.value)} + onKeyDown={handleKeyPress} + componentSize="small" + /> + setCurrentVal(e.target.value)} + onKeyDown={handleKeyPress} + componentSize="small" + /> + + + + + + + ); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemCustomField.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemCustomField.tsx index 36c0090c83..d2b9042e5f 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemCustomField.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemCustomField.tsx @@ -8,10 +8,9 @@ import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { ButtonV2 } from "@ndla/button"; -import { spacing, colors } from "@ndla/core"; import { AddLine } from "@ndla/icons/action"; +import { Button, Heading } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node, Metadata } from "@ndla/types-taxonomy"; import ConstantMetaField from "./ConstantMetaField"; import CustomFieldComponent from "./CustomFieldComponent"; @@ -41,21 +40,27 @@ import ToggleExplanationSubject from "../../subjectMenuOptions/ToggleExplanation import ToggleProgrammeSubject from "../../subjectMenuOptions/ToggleProgrammeSubject"; import GroupTopicResources from "../../topicMenuOptions/GroupTopicResources"; +const ContentWrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "small", + }, +}); + +const Wrapper = styled("div", { + base: { + width: "100%", + }, +}); + +const StyledButton = styled(Button, { base: { alignSelf: "flex-end" } }); + interface Props { node: Node; onCurrentNodeChanged: (node: Node) => void; } -const StyledFilterWrapper = styled.div` - background-color: white; - padding: calc(${spacing.small} / 2); - position: relative; -`; - -const StyledButton = styled(ButtonV2)` - color: ${colors.brand.greyDark}; -`; - const MenuItemCustomField = ({ node, onCurrentNodeChanged }: Props) => { const { t } = useTranslation(); const { id, metadata } = node; @@ -102,24 +107,18 @@ const MenuItemCustomField = ({ node, onCurrentNodeChanged }: Props) => { }); }; - const programmeSettings = ( - <> - - - ); + const programmeSettings = ; const topicSettings = ( - <> - - onCurrentNodeChanged({ - ...node, - metadata: { ...node.metadata, ...partialMeta }, - }) - } - /> - + + onCurrentNodeChanged({ + ...node, + metadata: { ...node.metadata, ...partialMeta }, + }) + } + /> ); const subjectSettings = ( @@ -132,9 +131,6 @@ const MenuItemCustomField = ({ node, onCurrentNodeChanged }: Props) => { @@ -142,31 +138,34 @@ const MenuItemCustomField = ({ node, onCurrentNodeChanged }: Props) => { ); return ( - <> - {nodeType === PROGRAMME && programmeSettings} - {nodeType === SUBJECT_NODE && subjectSettings} - {nodeType === TOPIC_NODE && topicSettings} - {filterHardcodedMetadataValues() - .sort((a, b) => a[0].localeCompare(b[0])) - .map(([key, value]) => ( - - ))} - {isOpen ? ( - setOpen(false)} /> - ) : ( - - setOpen(true)} - > + + +

{t("taxonomy.metadata.customFields.alterFields")}

+
+ + {nodeType === PROGRAMME && programmeSettings} + {nodeType === SUBJECT_NODE && subjectSettings} + {nodeType === TOPIC_NODE && topicSettings} + {filterHardcodedMetadataValues() + .sort((a, b) => a[0].localeCompare(b[0])) + .map(([key, value]) => ( + + ))} + {isOpen ? ( + setOpen(false)} /> + ) : ( + setOpen(true)}> {t("taxonomy.metadata.customFields.addField")} -
- )} - + )} + +
); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemEditField.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemEditField.tsx deleted file mode 100644 index f14aa28c93..0000000000 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/MenuItemEditField.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2016-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { ReactNode, useState, KeyboardEvent } from "react"; -import styled from "@emotion/styled"; -import { spacing } from "@ndla/core"; -import { Done } from "@ndla/icons/editor"; -import CustomFieldButton from "./CustomFieldButton"; -import RoundIcon from "../../../../../components/RoundIcon"; -import Spinner from "../../../../../components/Spinner"; -import handleError from "../../../../../util/handleError"; -import { StyledErrorMessage, StyledMenuItemInputField } from "../../styles"; - -const StyledMenuItemEditField = styled("div")` - display: flex; - align-items: center; - margin: ${spacing.xsmall}; -`; - -interface Props { - onSubmit: (input: string) => Promise; - onClose: () => void; - currentVal?: string; - icon?: ReactNode; - messages?: { - errorMessage?: string; - }; - dataTestid?: string; - placeholder?: string; - autoFocus?: boolean; - initialValue?: string; -} - -const MenuItemEditField = ({ - onSubmit, - onClose, - currentVal = "", - icon, - messages = {}, - dataTestid = "inlineEditInput", - placeholder, - autoFocus, -}: Props) => { - const [status, setStatus] = useState("initial"); - const [input, setInput] = useState(currentVal); - - const handleSubmit = async () => { - setStatus("loading"); - try { - await onSubmit(input); - setStatus("success"); - onClose(); - } catch (e) { - handleError(e); - setStatus("error"); - } - }; - - const handleKeyPress = (e: KeyboardEvent) => { - if (e.key === "Escape") { - setStatus("initial"); - } - if (e.key === "Enter") { - handleSubmit(); - } - }; - - const value = input ?? currentVal; - return ( - <> - - - setInput(e.target.value)} - onKeyDown={handleKeyPress} - // eslint-disable-next-line jsx-a11y/no-autofocus - autoFocus={autoFocus} - /> - - {status === "loading" ? ( - - ) : ( - - )} - - - {status === "error" && ( - {messages.errorMessage} - )} - - ); -}; - -export default MenuItemEditField; diff --git a/src/containers/StructurePage/folderComponents/styles.ts b/src/containers/StructurePage/folderComponents/styles.ts deleted file mode 100644 index eb3ddf1a6d..0000000000 --- a/src/containers/StructurePage/folderComponents/styles.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2021-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import styled from "@emotion/styled"; -import { spacing, colors } from "@ndla/core"; - -export const StyledErrorMessage = styled("div")` - color: ${colors.support.red}; - text-align: center; -`; - -export const StyledMenuItemInputField = styled("input")` - margin-right: calc(${spacing.small} / 2); - max-height: ${spacing.normal}; - width: 100%; -`; - -export const StyledMenuItemEditField = styled("div")` - display: flex; - align-items: center; - margin: ${spacing.xsmall}; -`; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/AddNodeTranslation.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/AddNodeTranslation.tsx index 83a9c0ba3e..f327815b94 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/AddNodeTranslation.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/AddNodeTranslation.tsx @@ -79,7 +79,7 @@ const AddNodeTranslation = ({ onAddTranslation, availableLanguages, defaultName return ( - +

{t("taxonomy.changeName.addNewTranslation")}

@@ -90,7 +90,7 @@ const AddNodeTranslation = ({ onAddTranslation, availableLanguages, defaultName positioning={{ sameWidth: true }} > {t("taxonomy.changeName.language")} - + @@ -104,8 +104,7 @@ const AddNodeTranslation = ({ onAddTranslation, availableLanguages, defaultName - - diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx index 815c0877e8..ffc4a6ca92 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ChangeNodeName.tsx @@ -7,36 +7,29 @@ */ import { FieldArray, Formik, FormikProps } from "formik"; -import { useCallback, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { Portal } from "@ark-ui/react"; import { useQueryClient } from "@tanstack/react-query"; -import { DeleteBinLine, PencilFill } from "@ndla/icons/action"; +import { DeleteBinLine } from "@ndla/icons/action"; import { - Button, - DialogBody, - DialogCloseTrigger, - DialogContent, - DialogHeader, - DialogRoot, - DialogTitle, - DialogTrigger, + Text, FieldErrorMessage, FieldInput, FieldLabel, FieldRoot, + Heading, IconButton, + Spinner, } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; -import { Translation, Node, NodeType } from "@ndla/types-taxonomy"; +import { Translation, Node } from "@ndla/types-taxonomy"; import AddNodeTranslation from "./AddNodeTranslation"; import { Row } from "../../../../components"; -import { DialogCloseButton } from "../../../../components/DialogCloseButton"; import { FormField } from "../../../../components/FormField"; -import { FormActionsContainer, FormikForm } from "../../../../components/FormikForm"; +import { FormActionsContainer } from "../../../../components/FormikForm"; import validateFormik, { RulesType } from "../../../../components/formikValidationSchema"; +import FormWrapper from "../../../../components/FormWrapper"; import SaveButton from "../../../../components/SaveButton"; -import Spinner from "../../../../components/Spinner"; import { subjectpageLanguages } from "../../../../i18n2"; import { useDeleteNodeTranslationMutation, @@ -47,8 +40,6 @@ import { nodeQueryKeys, useNode } from "../../../../modules/nodes/nodeQueries"; import { isFormikFormDirty } from "../../../../util/formHelper"; import handleError from "../../../../util/handleError"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; -import { StyledErrorMessage } from "../styles"; const InputWrapper = styled("div", { base: { @@ -57,6 +48,12 @@ const InputWrapper = styled("div", { }, }); +const Wrapper = styled("div", { + base: { + width: "100%", + }, +}); + interface FormikTranslationFormValues { translations: Translation[]; name: string; @@ -64,7 +61,6 @@ interface FormikTranslationFormValues { interface Props { node: Node; - editModeHandler: EditModeHandler; } const rules: RulesType = { @@ -76,41 +72,7 @@ const rules: RulesType = { }, }; -const ChangeNodeName = ({ editModeHandler: { editMode, toggleEditMode }, node }: Props) => { - const { t } = useTranslation(); - - const onModalChange = useCallback( - (open: boolean) => { - if (open) { - toggleEditMode("changeSubjectName"); - } else toggleEditMode(""); - }, - [toggleEditMode], - ); - - return ( - onModalChange(details.open)}> - - - - - - - - - - ); -}; - -interface ModalProps { - node: Node; - nodeType?: NodeType; -} - -const ChangeNodeNameContent = ({ node, nodeType = "SUBJECT" }: ModalProps) => { +const ChangeNodeName = ({ node }: Props) => { const { t } = useTranslation(); const [updateError, setUpdateError] = useState(""); const [saved, setSaved] = useState(false); @@ -173,7 +135,7 @@ const ChangeNodeNameContent = ({ node, nodeType = "SUBJECT" }: ModalProps) => { handleError(e); setUpdateError(t("taxonomy.changeName.updateError")); await qc.invalidateQueries({ - queryKey: nodeQueryKeys.nodes({ nodeType: nodeType, taxonomyVersion }), + queryKey: nodeQueryKeys.nodes({ nodeType: "SUBJECT", taxonomyVersion }), }); await qc.invalidateQueries({ @@ -185,7 +147,7 @@ const ChangeNodeNameContent = ({ node, nodeType = "SUBJECT" }: ModalProps) => { if (promises.length > 0) { await qc.invalidateQueries({ - queryKey: nodeQueryKeys.nodes({ nodeType: nodeType, taxonomyVersion }), + queryKey: nodeQueryKeys.nodes({ nodeType: "SUBJECT", taxonomyVersion }), }); await qc.invalidateQueries({ @@ -201,7 +163,7 @@ const ChangeNodeNameContent = ({ node, nodeType = "SUBJECT" }: ModalProps) => { } if (nodeWithoutTranslationsQuery.isError || !nodeWithoutTranslationsQuery.data) { - return {t("taxonomy.changeName.loadError")}; + return {t("taxonomy.changeName.loadError")}; } const initialValues = { @@ -210,116 +172,116 @@ const ChangeNodeNameContent = ({ node, nodeType = "SUBJECT" }: ModalProps) => { }; return ( - <> - - {t("taxonomy.changeName.title")} - - - - {}} - validate={(values) => { - const errors = values.translations.map((translation) => validateFormik(translation, rules, t)); + + +

{t("taxonomy.changeName.buttonTitle")}

+
+ {}} + validate={(values) => { + const errors = values.translations.map((translation) => validateFormik(translation, rules, t)); - const nameErrors = validateFormik( - { name: values.name }, - { - name: { - required: true, - }, + const nameErrors = validateFormik( + { name: values.name }, + { + name: { + required: true, }, - t, - ); - if (errors.some((err) => Object.keys(err).length > 0) || Object.keys(nameErrors).length > 0) { - return { translations: errors, ...nameErrors }; - } - }} - enableReinitialize={true} - > - {(formik) => { - const { values, dirty, isSubmitting, isValid } = formik; - const takenLanguages = values.translations.reduce((prev, curr) => ({ ...prev, [curr.language]: "" }), {}); - const availableLanguages = subjectpageLanguages.filter( - (trans) => !Object.prototype.hasOwnProperty.call(takenLanguages, trans), - ); - const formIsDirty: boolean = isFormikFormDirty({ - values, - initialValues, - dirty, - }); + }, + t, + ); + if (errors.some((err) => Object.keys(err).length > 0) || Object.keys(nameErrors).length > 0) { + return { translations: errors, ...nameErrors }; + } + }} + enableReinitialize={true} + > + {(formik) => { + const { values, dirty, isSubmitting, isValid } = formik; + const takenLanguages = values.translations.reduce((prev, curr) => ({ ...prev, [curr.language]: "" }), {}); + const availableLanguages = subjectpageLanguages.filter( + (trans) => !Object.prototype.hasOwnProperty.call(takenLanguages, trans), + ); + const formIsDirty: boolean = isFormikFormDirty({ + values, + initialValues, + dirty, + }); + + if (formIsDirty) { + setUpdateError(""); + setSaved(false); + } + return ( + + + {({ field, meta }) => ( + + {t("taxonomy.changeName.defaultName")} + + {meta.error} + + )} + + {values.translations.length === 0 && <>{t("taxonomy.changeName.noTranslations")}} + + {({ push, remove }) => ( + <> + {values.translations.map((trans, i) => ( + + + {({ field, meta }) => ( + + {t(`languages.${trans.language}`)} + + + remove(i)} + size="small" + data-testid={`subjectName_${trans.language}_delete`} + > + + + + {meta.error} + + )} + + + ))} + + + )} + - if (formIsDirty) { - setUpdateError(""); - setSaved(false); - } - return ( - - - {({ field, meta }) => ( - - {t("taxonomy.changeName.defaultName")} - - {meta.error} - - )} - - {values.translations.length === 0 && <>{t("taxonomy.changeName.noTranslations")}} - - {({ push, remove }) => ( - <> - {values.translations.map((trans, i) => ( - - - {({ field, meta }) => ( - - {t(`languages.${trans.language}`)} - - - remove(i)} - data-testid={`subjectName_${trans.language}_delete`} - > - - - - {meta.error} - - )} - - - ))} - - - )} - - - - - - onSubmit(formik)} - disabled={!isValid} - /> - - {updateError && {updateError}} - - ); - }} - -
- + + onSubmit(formik)} + disabled={!isValid} + size="small" + /> + + {updateError && {updateError}} + + ); + }} + + ); }; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx index 2d128ad1d0..e04bca014b 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx @@ -7,7 +7,6 @@ */ import { useMemo } from "react"; -import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; import { SelectContent, @@ -20,26 +19,9 @@ import { import { styled } from "@ndla/styled-system/jsx"; import { GenericSelectItem, GenericSelectTrigger } from "../../../../components/abstractions/Select"; -const StyledSelectRoot = styled(SelectRoot, { - base: { - flexDirection: "row", - justifyContent: "space-between", - width: "100%", - }, -}); - const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { - base: { - maxWidth: "surface.xsmall", - }, -}); - -const StyledWrapper = styled("div", { - base: { - margin: "xxsmall", - }, + base: { flexGrow: "1" }, }); - interface Option { key: string; value: string; @@ -53,8 +35,6 @@ interface Props { } const TaxonomyMetadataDropdown = ({ options, field, customFields, updateCustomFields, messages }: Props) => { - const { t } = useTranslation(); - const collection = useMemo(() => { return createListCollection({ items: options, @@ -64,34 +44,32 @@ const TaxonomyMetadataDropdown = ({ options, field, customFields, updateCustomFi }, [options]); return ( - - - updateCustomFields({ - ...customFields, - [field]: details.value[0], - }) - } - positioning={{ sameWidth: true }} - > - {messages["title"]} - - - - - - {collection.items.map((item) => ( - - {item.value} - - ))} - - - - - + + updateCustomFields({ + ...customFields, + [field]: details.value[0], + }) + } + positioning={{ sameWidth: true }} + > + {messages["title"]} + + + + + + {collection.items.map((item) => ( + + {item.value} + + ))} + + + + ); }; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleExplanationSubject.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleExplanationSubject.tsx index beb89be19c..6f1752e5a7 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleExplanationSubject.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleExplanationSubject.tsx @@ -10,26 +10,18 @@ import { useTranslation } from "react-i18next"; import { DeleteBinLine } from "@ndla/icons/action"; import { IconButton, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; -import RoundIcon from "../../../../components/RoundIcon"; import { TAXONOMY_CUSTOM_FIELD_SUBJECT_FOR_CONCEPT } from "../../../../constants"; -import { StyledMenuItemEditField } from "../styles"; interface Props { customFields: Record; updateFields: (newFields: Record) => void; } -const StyledSwitchRoot = styled(SwitchRoot, { +const SwitchWrapper = styled("div", { base: { - // TODO: Remove this once we redesign structure options - marginInlineEnd: "3xsmall", - flex: "1", - }, -}); - -const StyledSwitchLabel = styled(SwitchLabel, { - base: { - flex: "1", + display: "flex", + gap: "3xsmall", + alignSelf: "flex-end", }, }); @@ -38,22 +30,21 @@ const ToggleExplanationSubject = ({ customFields, updateFields }: Props) => { const isToggled = customFields[TAXONOMY_CUSTOM_FIELD_SUBJECT_FOR_CONCEPT]?.toLowerCase() === "true"; return ( - - - + updateFields({ ...customFields, [TAXONOMY_CUSTOM_FIELD_SUBJECT_FOR_CONCEPT]: details.checked.toString() }) } > - {t("taxonomy.metadata.customFields.explanationSubject")} + {t("taxonomy.metadata.customFields.explanationSubject")} - + { delete customFields[TAXONOMY_CUSTOM_FIELD_SUBJECT_FOR_CONCEPT]; @@ -62,7 +53,7 @@ const ToggleExplanationSubject = ({ customFields, updateFields }: Props) => { > - + ); }; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleProgrammeSubject.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleProgrammeSubject.tsx index 53991bbbfa..5abce5329f 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleProgrammeSubject.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/ToggleProgrammeSubject.tsx @@ -10,22 +10,18 @@ import { useTranslation } from "react-i18next"; import { DeleteBinLine } from "@ndla/icons/action"; import { IconButton, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; -import RoundIcon from "../../../../components/RoundIcon"; import { TAXONOMY_CUSTOM_FIELD_PROGRAMME_SUBJECT } from "../../../../constants"; -import { StyledMenuItemEditField } from "../styles"; -const StyledSwitchRoot = styled(SwitchRoot, { +const SwitchWrapper = styled("div", { base: { - // TODO: Remove this once we redesign structure options - marginInlineEnd: "3xsmall", - flex: "1", + width: "100%", + display: "flex", + gap: "3xsmall", }, }); -const StyledSwitchLabel = styled(SwitchLabel, { - base: { - flex: "1", - }, +const StyledSwitchRoot = styled(SwitchRoot, { + base: { flexGrow: "1" }, }); interface Props { @@ -38,8 +34,7 @@ const ToggleProgrammeSubject = ({ customFields, updateFields }: Props) => { const isToggled = customFields[TAXONOMY_CUSTOM_FIELD_PROGRAMME_SUBJECT]?.toLowerCase() === "true"; return ( - - + @@ -49,14 +44,14 @@ const ToggleProgrammeSubject = ({ customFields, updateFields }: Props) => { }) } > - {t("taxonomy.metadata.customFields.programmeSubject")} + {t("taxonomy.metadata.customFields.programmeSubject")} { delete customFields[TAXONOMY_CUSTOM_FIELD_PROGRAMME_SUBJECT]; @@ -65,7 +60,7 @@ const ToggleProgrammeSubject = ({ customFields, updateFields }: Props) => { > - + ); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx index beb6ebc491..9b9b6d075c 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx @@ -6,67 +6,59 @@ * */ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; -import { spacing, colors } from "@ndla/core"; -import { Copy, FileCopyLine } from "@ndla/icons/action"; -import { Done } from "@ndla/icons/editor"; -import { Spinner, Button } from "@ndla/primitives"; +import { ErrorWarningLine } from "@ndla/icons/common"; +import { CheckLine } from "@ndla/icons/editor"; +import { Text, Spinner, MessageBox } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeChild, NodeType } from "@ndla/types-taxonomy"; -import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import RoundIcon from "../../../../components/RoundIcon"; -import { EditMode } from "../../../../interfaces"; import { cloneDraft } from "../../../../modules/draft/draftApi"; import { learningpathCopy } from "../../../../modules/learningpath/learningpathApi"; import { cloneNode, fetchNodeResources, postResourceForNode } from "../../../../modules/nodes/nodeApi"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; import NodeSearchDropdown from "../sharedMenuOptions/components/NodeSearchDropdown"; -type ActionType = Extract; +type ActionType = "copyResources" | "cloneResources"; interface Props { currentNode: Node; nodeType: NodeType; - editModeHandler: EditModeHandler; type: ActionType; } -const StyledSpinner = styled(Spinner)` - margin: 0px 4px; -`; - -const Wrapper = styled.div` - display: flex; - align-items: center; - margin: ${spacing.xsmall}; -`; - -const LinkWrapper = styled.div` - a { - color: ${colors.white}; - &:hover { - color: ${colors.white}; - } - } - margin-top: 0.5em; -`; - -const StyledDiv = styled.div` - display: flex; - align-items: center; - margin-left: ${spacing.normal}; -`; - -const StyledDone = styled(Done)` - margin: 0px 4px; - color: green; -`; - -const CopyNodeResources = ({ editModeHandler: { editMode, toggleEditMode }, currentNode, nodeType, type }: Props) => { +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "small", + width: "100%", + }, +}); + +const StyledCheckLine = styled(CheckLine, { + base: { + fill: "stroke.success", + }, +}); + +const StatusIndicatorContent = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + }, +}); + +const StyledErrorTextWrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + }, +}); + +const CopyNodeResources = ({ currentNode, nodeType, type }: Props) => { const { t, i18n: { language }, @@ -78,13 +70,6 @@ const CopyNodeResources = ({ editModeHandler: { editMode, toggleEditMode }, curr const [failedResources, setFailedResources] = useState([]); const [showDisplay, setShowDisplay] = useState(false); const [done, setDone] = useState(false); - const [showAlert, setShowAlert] = useState(false); - - useEffect(() => { - setShowAlert(failedResources.length !== 0 && done); - }, [failedResources, done]); - - const toggleEditModeFunc = () => toggleEditMode(type); const prepareForAction = () => { setFailedResources([]); @@ -92,7 +77,6 @@ const CopyNodeResources = ({ editModeHandler: { editMode, toggleEditMode }, curr setCount(0); setTotalAmount(0); setShowDisplay(true); - toggleEditModeFunc(); }; const cloneOrCopyResources = async (node: Node, type: ActionType) => { @@ -171,61 +155,52 @@ const CopyNodeResources = ({ editModeHandler: { editMode, toggleEditMode }, curr } }; - if (editMode === type) { - return ( - - } /> - cloneOrCopyResources(node, type)} - searchNodeType={"TOPIC"} - filter={(node) => { - return ( - !!node.path && - !node.paths?.some((p) => { - const split = p.replace("/", "").split("/"); - return split[split.length - 2] === currentNode.id.replace("urn:", ""); - }) - ); - }} - /> - - ); - } - const prefixText = t(`taxonomy.${type}.${done ? "done" : "waiting"}`); return ( - <> - + + cloneOrCopyResources(node, type)} + searchNodeType={"TOPIC"} + filter={(node) => { + return ( + !!node.path && + !node.paths?.some((p) => { + const split = p.replace("/", "").split("/"); + return split[split.length - 2] === currentNode.id.replace("urn:", ""); + }) + ); + }} + /> {showDisplay && ( - - {done ? : } - {`${prefixText} (${count}/${totalAmount})`} - + + {done ? : } + {`${prefixText} (${count}/${totalAmount})`} + + )} + + {failedResources.length > 0 && ( + + + + {t(`taxonomy.${type}.error`)} +
+ {failedResources.map((res, index) => ( +
+ +
+ ))} +
+
+
)} - setShowAlert(false)} - text={t(`taxonomy.${type}.error`)} - > - {failedResources.map((res, index) => ( - - - - ))} - - +
); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/GroupTopicResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/GroupTopicResources.tsx index 5ab6f43517..28fb06ed69 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/GroupTopicResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/GroupTopicResources.tsx @@ -19,15 +19,13 @@ import { useUpdateNodeMetadataMutation } from "../../../../modules/nodes/nodeMut import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { getRootIdForNode, isRootNode } from "../../../../modules/nodes/nodeUtil"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { StyledMenuItemEditField } from "../styles"; interface Props { node: Node; - hideIcon?: boolean; onChanged?: (newMeta: Partial) => void; } -const GroupTopicResources = ({ node, hideIcon, onChanged }: Props) => { +const GroupTopicResources = ({ node, onChanged }: Props) => { const { t, i18n } = useTranslation(); const updateNodeMetadata = useUpdateNodeMetadataMutation(); const qc = useQueryClient(); @@ -62,21 +60,20 @@ const GroupTopicResources = ({ node, hideIcon, onChanged }: Props) => { const nodeResources = node.metadata?.customFields[TAXONOMY_CUSTOM_FIELD_TOPIC_RESOURCES]; const isGrouped = (nodeResources ?? TAXONOMY_CUSTOM_FIELD_GROUPED_RESOURCE) === TAXONOMY_CUSTOM_FIELD_GROUPED_RESOURCE; + return ( - - - {t("taxonomy.metadata.customFields.resourceGroupPlaceholder")} - - {isGrouped ? "G" : "U"} - - - - + + {t("taxonomy.metadata.customFields.resourceGroupPlaceholder")} + + {isGrouped ? "G" : "U"} + + + ); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx index 2e67a25b11..d512bb2beb 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx @@ -7,18 +7,16 @@ */ import partition from "lodash/partition"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; -import { colors } from "@ndla/core"; -import { CheckLine, Done } from "@ndla/icons/editor"; -import { Button, Spinner } from "@ndla/primitives"; +import { ErrorWarningLine } from "@ndla/icons/common"; +import { CheckLine } from "@ndla/icons/editor"; +import { Button, Heading, MessageBox, Spinner, Text } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { IArticle } from "@ndla/types-backend/draft-api"; import { ILearningPathV2 } from "@ndla/types-backend/learningpath-api"; import { Node } from "@ndla/types-taxonomy"; -import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import { FormActionsContainer } from "../../../../components/FormikForm"; import { PUBLISHED } from "../../../../constants"; import { fetchDrafts, updateStatusDraft } from "../../../../modules/draft/draftApi"; import { fetchLearningpaths, updateStatusLearningpath } from "../../../../modules/learningpath/learningpathApi"; @@ -30,30 +28,38 @@ import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; interface Props { node: Node; } -const StyledDiv = styled.div` - display: flex; - align-items: center; - padding-left: 1.2em; -`; -const LinkWrapper = styled.div` - a { - color: ${colors.white}; - &:hover { - color: ${colors.white}; - } - } - margin-top: 0.5em; -`; +const StatusIndicatorContent = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + }, +}); -const StyledSpinner = styled(Spinner)` - margin: 0px 4px; -`; +const StyledErrorTextWrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + }, +}); -const StyledDone = styled(Done)` - margin: 0px 4px; - color: green; -`; +const StyledCheckLine = styled(CheckLine, { + base: { fill: "stroke.success" }, +}); + +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "small", + }, +}); + +const StyledButton = styled(Button, { + base: { + alignSelf: "flex-end", + }, +}); interface BaseResource { name: string; @@ -71,14 +77,8 @@ const PublishChildNodeResources = ({ node }: Props) => { const [publishedCount, setPublishedCount] = useState(0); const [publishableCount, setPublishableCount] = useState(0); const [done, setDone] = useState(false); - const [showAlert, setShowAlert] = useState(false); - const [showConfirmation, setShowConfirmation] = useState(false); const qc = useQueryClient(); - useEffect(() => { - setShowAlert(failedResources.length !== 0 && done); - }, [failedResources, done]); - const publishResources = async () => { setFailedResources([]); setDone(false); @@ -143,57 +143,42 @@ const PublishChildNodeResources = ({ node }: Props) => { const publishText = t(`taxonomy.publish.${done ? "done" : "waiting"}`); return ( - <> - + + +

{t("taxonomy.publish.button")}

+
+ + + {t("taxonomy.publish.info")} + + publishResources()}>{t("taxonomy.publish.button")} {showDisplay && ( - - {done ? : } - {`${publishText} (${publishedCount}/${publishableCount})`} - + + {done ? : } + {`${publishText} (${publishedCount}/${publishableCount})`} + + )} + {failedResources.length > 0 && ( + + + + {t("taxonomy.publish.error")} +
+ {failedResources.map((res, index) => ( +
+ +
+ ))} +
+
+
)} - setShowAlert(false)} - text={t("taxonomy.publish.error")} - > - {failedResources.map((res, index) => ( - - - - ))} - - setShowConfirmation(false)} - > - - - - - - +
); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx index d33da88c76..0c6e941159 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx @@ -8,35 +8,40 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { PencilFill } from "@ndla/icons/action"; -import { Button } from "@ndla/primitives"; +import { ErrorWarningLine } from "@ndla/icons/common"; +import { Button, Heading, MessageBox, Spinner, Text } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { Node } from "@ndla/types-taxonomy"; -import { AlertDialog } from "../../../../components/AlertDialog/AlertDialog"; -import { FormActionsContainer } from "../../../../components/FormikForm"; -import Overlay from "../../../../components/Overlay"; -import Spinner from "../../../../components/Spinner"; import { usePutResourcesPrimaryMutation } from "../../../../modules/nodes/nodeMutations"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; -import { StyledErrorMessage } from "../styles"; + +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "small", + }, +}); + +const StyledButton = styled(Button, { + base: { + alignSelf: "flex-end", + }, +}); interface Props { node: Node; recursive?: boolean; - editModeHandler: EditModeHandler; } -const SetResourcesPrimary = ({ node, recursive = false, editModeHandler: { editMode, toggleEditMode } }: Props) => { +const SetResourcesPrimary = ({ node, recursive = false }: Props) => { const { t } = useTranslation(); const [error, setError] = useState(); const { mutateAsync, isPending } = usePutResourcesPrimaryMutation(); const { taxonomyVersion } = useTaxonomyVersion(); - const toggleConnectedResourcesPrimary = () => toggleEditMode("setResourcesPrimary"); - const setConnectedResourcesPrimary = async () => { setError(undefined); - toggleConnectedResourcesPrimary(); await mutateAsync( { taxonomyVersion, id: node.id, recursive }, @@ -45,31 +50,20 @@ const SetResourcesPrimary = ({ node, recursive = false, editModeHandler: { editM }; return ( - <> - - - - - - - - {isPending && } - {isPending && } - {error && {error}} - + + +

{t("taxonomy.resourcesPrimary.recursiveButtonText")}

+
+ + + {recursive ? t("taxonomy.resourcesPrimary.recursiveText") : t("taxonomy.resourcesPrimary.text")} + + + {t("alertModal.continue")} + {isPending && } + + {error && {error}} +
); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx index 44c31fe407..591eabe9d1 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx @@ -6,20 +6,16 @@ * */ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; import { useQueryClient } from "@tanstack/react-query"; -import { spacing, colors } from "@ndla/core"; -import { FileTextLine } from "@ndla/icons/common"; -import { SubjectMaterial } from "@ndla/icons/contentType"; -import { Done } from "@ndla/icons/editor"; -import { ComboboxLabel, Spinner, Button } from "@ndla/primitives"; +import { CheckLine } from "@ndla/icons/editor"; +import { Text, ComboboxLabel, Spinner } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; import { IMultiSearchSummary } from "@ndla/types-backend/search-api"; import { Node } from "@ndla/types-taxonomy"; import { GenericComboboxInput, GenericComboboxItemContent } from "../../../../components/abstractions/Combobox"; import { GenericSearchCombobox } from "../../../../components/Form/GenericSearchCombobox"; -import RoundIcon from "../../../../components/RoundIcon"; import { fetchDraft, updateDraft } from "../../../../modules/draft/draftApi"; import { TOPIC_NODE } from "../../../../modules/nodes/nodeApiTypes"; import { usePutNodeMutation } from "../../../../modules/nodes/nodeMutations"; @@ -27,48 +23,30 @@ import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; import { useSearch } from "../../../../modules/search/searchQueries"; import { usePaginatedQuery } from "../../../../util/usePaginatedQuery"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import { EditModeHandler } from "../SettingsMenuDropdownType"; -import { StyledErrorMessage } from "../styles"; interface Props { node: Node; rootNodeId: string; - editModeHandler: EditModeHandler; } -const Wrapper = styled.div` - display: flex; - align-items: center; - margin: ${spacing.small}; -`; +const Wrapper = styled("div", { + base: { + display: "flex", + flexDirection: "column", + gap: "3xsmall", + width: "100%", + }, +}); -const StyledMenuWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: baseline; -`; +const StyledCheckLine = styled(CheckLine, { + base: { + fill: "stroke.success", + }, +}); -const MenuContent = styled.div` - display: flex; - flex-direction: row; - align-items: center; -`; - -const StyledActionContent = styled.div` - padding-left: ${spacing.normal}; -`; - -const StyledSuccessIcon = styled(Done)` - border-radius: 90px; - margin: 5px; - background-color: ${colors.support.green}; - color: ${colors.white}; -`; - -const SwapTopicArticle = ({ node, rootNodeId, editModeHandler: { editMode, toggleEditMode } }: Props) => { +const SwapTopicArticle = ({ node, rootNodeId }: Props) => { const { t, i18n } = useTranslation(); const putNodeMutation = usePutNodeMutation(); - const toggleEditModeFunc = () => toggleEditMode("swapTopicArticle"); const [error, setError] = useState(undefined); const { taxonomyVersion } = useTaxonomyVersion(); const qc = useQueryClient(); @@ -76,16 +54,11 @@ const SwapTopicArticle = ({ node, rootNodeId, editModeHandler: { editMode, toggl const searchQuery = useSearch( { query: delayedQuery, language: i18n.language, page }, - { placeholderData: (prev) => prev, enabled: editMode === "swapTopicArticle" }, + { placeholderData: (prev) => prev }, ); - useEffect(() => { - setError(undefined); - }, [editMode]); - const handleSubmit = async (topic: IMultiSearchSummary) => { setError(undefined); - toggleEditModeFunc(); try { await putNodeMutation.mutateAsync({ id: node.id, @@ -116,61 +89,49 @@ const SwapTopicArticle = ({ node, rootNodeId, editModeHandler: { editMode, toggl } }; - if (editMode === "swapTopicArticle") { - return ( - - } /> - item.title.title} - itemToValue={(item) => item.id.toString()} - inputValue={query} - onInputValueChange={(details) => setQuery(details.inputValue)} - isSuccess={searchQuery.isSuccess} - paginationData={searchQuery.data} - onPageChange={(details) => setPage(details.page)} - onValueChange={(details) => handleSubmit(details.items[0])} - css={{ width: "100%" }} - renderItem={(item) => ( - - )} - > - {t("taxonomy.swapTopicArticle.info")} - - - - ); - } - return ( - - - - {putNodeMutation.isPending && ( - - - + + item.title.title} + itemToValue={(item) => item.id.toString()} + inputValue={query} + onInputValueChange={(details) => setQuery(details.inputValue)} + isSuccess={searchQuery.isSuccess} + paginationData={searchQuery.data} + onPageChange={(details) => setPage(details.page)} + onValueChange={(details) => handleSubmit(details.items[0])} + css={{ width: "100%" }} + renderItem={(item) => ( + )} + > + {t("taxonomy.swapTopicArticle.info")} + + +
+ {putNodeMutation.isPending && } {putNodeMutation.isSuccess && ( - - + + {t("taxonomy.swapTopicArticle.success")} - + + )} + {error && ( + + {error} + )} - {error && {t(error)}} - - +
+
); }; diff --git a/src/containers/StructurePage/resourceComponents/GrepCodesForm.tsx b/src/containers/StructurePage/resourceComponents/GrepCodesForm.tsx index 93456f959f..2f49954931 100644 --- a/src/containers/StructurePage/resourceComponents/GrepCodesForm.tsx +++ b/src/containers/StructurePage/resourceComponents/GrepCodesForm.tsx @@ -25,7 +25,7 @@ const StyledText = styled(Text, { interface Props { codes: string[]; onUpdate: (grepCodes: string[]) => Promise; - close: () => void; + close?: () => void; } interface Values { @@ -45,7 +45,7 @@ const GrepCodesForm = ({ codes, onUpdate, close }: Props) => { await onUpdate(values.grepCodes); helpers.resetForm({ values: values }); setLoading(false); - close(); + close?.(); } catch (err) { setError(true); setLoading(false); @@ -61,9 +61,11 @@ const GrepCodesForm = ({ codes, onUpdate, close }: Props) => { - + {close && ( + + )} diff --git a/src/containers/StructurePage/resourceComponents/ResourceItems.tsx b/src/containers/StructurePage/resourceComponents/ResourceItems.tsx index 6f1c43c5e1..d08d5056ca 100644 --- a/src/containers/StructurePage/resourceComponents/ResourceItems.tsx +++ b/src/containers/StructurePage/resourceComponents/ResourceItems.tsx @@ -148,9 +148,7 @@ const ResourceItems = ({ resources, currentNodeId, contentMeta, contentMetaLoadi )} /> {deleteNodeResource.error && isError(deleteNodeResource.error) ? ( - - {`${t("taxonomy.errorMessage")}: ${deleteNodeResource.error.message}`} - + {`${t("taxonomy.errorMessage")}: ${deleteNodeResource.error.message}`} ) : null} = { [P in K]?: T; }; -export type EditMode = - | "changeSubjectName" - | "deleteTopic" - | "addExistingSubjectTopic" - | "openCustomFields" - | "toggleMetadataVisibility" - | "editGrepCodes" - | "moveExistingNode" - | "addTopic" - | "deleteSubject" - | "requestPublish" - | "deleteNode" - | "disconnectFromParent" - | "copyResources" - | "cloneResources" - | "copyRevisionDate" - | "swapTopicArticle" - | "setResourcesPrimary" - | "connectExistingNode" - | ""; - export interface SearchResultBase { totalCount: number; page?: number; diff --git a/src/phrases/phrases-en.ts b/src/phrases/phrases-en.ts index 1edb3c8783..5dc5f0453c 100644 --- a/src/phrases/phrases-en.ts +++ b/src/phrases/phrases-en.ts @@ -1863,6 +1863,8 @@ const phrases = { subjectLMA: "Responsible for the subject", subjectSA: "Language responsible for the subject", subjectDA: "Desk responsible for the subject", + keyPlaceholder: "Add key", + valuePlaceholder: "Add value", }, placeholders: { category: "Choose category", diff --git a/src/phrases/phrases-nb.ts b/src/phrases/phrases-nb.ts index 81a1147300..7a0236621f 100644 --- a/src/phrases/phrases-nb.ts +++ b/src/phrases/phrases-nb.ts @@ -1861,6 +1861,8 @@ const phrases = { subjectLMA: "LMA for faget", subjectSA: "SA for faget", subjectDA: "DA for faget", + keyPlaceholder: "Skriv inn nøkkel", + valuePlaceholder: "Skriv inn verdi", }, placeholders: { category: "Velg kategori", diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 0aed726c76..6ff424c42b 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -1862,6 +1862,8 @@ const phrases = { subjectLMA: "LMA for faget", subjectSA: "SA for faget", subjectDA: "DA for faget", + keyPlaceholder: "Skriv inn nøkkel", + valuePlaceholder: "Skriv inn verdi", }, placeholders: { category: "Velg kategori", From 5c60c8a9665373fce49578f83da530b0c74dd294 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Thu, 14 Nov 2024 12:06:57 +0100 Subject: [PATCH 010/170] Add info text when node with children can't be deleted --- .../sharedMenuOptions/DeleteNode.tsx | 20 +++++++++---------- src/phrases/phrases-en.ts | 1 + src/phrases/phrases-nb.ts | 1 + src/phrases/phrases-nn.ts | 1 + 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx index ebc1366c86..94d8f59923 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DeleteNode.tsx @@ -12,23 +12,19 @@ import { ErrorWarningLine } from "@ndla/icons/common"; import { Text, Button, Heading, MessageBox } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeChild } from "@ndla/types-taxonomy"; +import { FormActionsContainer } from "../../../../components/FormikForm"; import { ARCHIVED } from "../../../../constants"; import { updateStatusDraft } from "../../../../modules/draft/draftApi"; import { fetchNodes } from "../../../../modules/nodes/nodeApi"; import { useDeleteNodeConnectionMutation, useDeleteNodeMutation } from "../../../../modules/nodes/nodeMutations"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -const StyledButton = styled(Button, { - base: { - alignSelf: "flex-end", - }, -}); - const Wrapper = styled("div", { base: { display: "flex", flexDirection: "column", gap: "small", + width: "100%", }, }); @@ -96,13 +92,15 @@ const DeleteNode = ({ node, nodeChildren, onCurrentNodeChanged, rootNodeId }: Pr

{t("taxonomy.deleteNode")}

- + - {t("taxonomy.confirmDelete")} + {disabled ? t("taxonomy.deleteDisabled") : t("taxonomy.confirmDelete")} - - {t("alertModal.delete")} - + + + {error && {error}} ); diff --git a/src/phrases/phrases-en.ts b/src/phrases/phrases-en.ts index 5dc5f0453c..f86eb5dd04 100644 --- a/src/phrases/phrases-en.ts +++ b/src/phrases/phrases-en.ts @@ -1700,6 +1700,7 @@ const phrases = { currentVersion: "Current version", deleteNode: "Delete node", deleteResource: "Delete resource", + deleteDisabled: "Nodes with children can't be deleted", confirmDelete: "Are you sure you want to delete this node?", version: "Version", createResource: "Create new resource", diff --git a/src/phrases/phrases-nb.ts b/src/phrases/phrases-nb.ts index 7a0236621f..1252dea36b 100644 --- a/src/phrases/phrases-nb.ts +++ b/src/phrases/phrases-nb.ts @@ -1698,6 +1698,7 @@ const phrases = { currentVersion: "Nåværende versjon", deleteNode: "Slett node", deleteResource: "Slett ressurs", + deleteDisabled: "Noder med barn kan ikke slettes", confirmDelete: "Er du sikker på at du vil slette denne noden?", version: "Versjon", createResource: "Opprett ny ressurs", diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 6ff424c42b..0c04067f15 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -1699,6 +1699,7 @@ const phrases = { currentVersion: "Noverande versjon", deleteNode: "Slett node", deleteResource: "Slett ressurs", + deleteDisabled: "Noder med barn kan ikkje slettes", confirmDelete: "Er du sikker på at du vil slette denne noden?", version: "Versjon", createResource: "Opprett ny ressurs", From e6e888e09c2abe49cd9fb2894985e91d16c4faf8 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Thu, 14 Nov 2024 14:07:22 +0100 Subject: [PATCH 011/170] Remove CustomFieldButton --- .../components/CustomFieldButton.tsx | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldButton.tsx diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldButton.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldButton.tsx deleted file mode 100644 index ca0dd61ecf..0000000000 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/CustomFieldButton.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2016-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { ReactNode } from "react"; -import styled from "@emotion/styled"; -import { ButtonV2 } from "@ndla/button"; -import { colors } from "@ndla/core"; - -const StyledCustomFieldButton = styled(ButtonV2)` - &, - &:disabled { - height: 24px; - width: 24px; - min-width: 24px; - min-height: 24px; - background-color: ${colors.brand.greyDark}; - border-color: ${colors.brand.greyDark}; - padding: 0; - line-height: 16.9px; - } -`; - -interface Props { - disabled?: boolean; - onClick: () => void; - children: ReactNode; - "data-testid"?: string; -} - -const CustomFieldButton = ({ children, ...rest }: Props) => { - return {children}; -}; - -export default CustomFieldButton; From e4a35af7be120366c6d8e8c325e5978b1ee676dc Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Mon, 18 Nov 2024 08:49:26 +0100 Subject: [PATCH 012/170] Utilize mutation state from react-query --- .../sharedMenuOptions/ConnectExistingNode.tsx | 24 +++++-------- .../DisconnectFromParent.tsx | 12 ++----- .../PublishChildNodeResources.tsx | 3 +- .../topicMenuOptions/SetResourcesPrimary.tsx | 36 ++++++++++++------- src/phrases/phrases-en.ts | 1 + src/phrases/phrases-nb.ts | 1 + src/phrases/phrases-nn.ts | 1 + 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx index 97d14faa33..b4c7eaa648 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/ConnectExistingNode.tsx @@ -6,7 +6,6 @@ * */ -import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; import { CheckLine } from "@ndla/icons/editor"; @@ -27,6 +26,7 @@ const StatusIndicatorContent = styled("div", { base: { display: "flex", gap: "3xsmall", + alignItems: "center", }, }); @@ -36,6 +36,7 @@ const Wrapper = styled("div", { display: "flex", flexDirection: "column", gap: "3xsmall", + alignItems: "flex-start", }, }); @@ -46,15 +47,10 @@ const StyledCheckLine = styled(CheckLine, { const ConnectExistingNode = ({ currentNode, nodeType }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); - const { mutateAsync: connectNode } = usePostNodeConnectionMutation(); - const [error, setError] = useState(undefined); - const [loading, setLoading] = useState(false); - const [success, setSuccess] = useState(false); + const { mutateAsync: connectNode, isError, isPending, isSuccess } = usePostNodeConnectionMutation(); const qc = useQueryClient(); const handleSubmit = async (node: Node) => { - setLoading(true); - setError(undefined); await connectNode( { taxonomyVersion, @@ -68,14 +64,10 @@ const ConnectExistingNode = ({ currentNode, nodeType }: Props) => { language: i18n.language, }), }); - setSuccess(true); - setLoading(false); }, - onError: () => setError("taxonomy.errorMessage"), }, ); }; - return ( { }); }} /> -
- {loading && ( + <> + {isPending && ( {t("taxonomy.connectExistingLoading")} )} - {success && ( + {isSuccess && ( {t("taxonomy.connectExistingSuccess")} )} - {error && {t(error)}} -
+ {isError && {t("taxonomy.errorMessage")}} +
); }; diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx index f2a6cbcc37..6b4923c09c 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/DisconnectFromParent.tsx @@ -6,7 +6,6 @@ * */ -import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { useQueryClient } from "@tanstack/react-query"; @@ -35,16 +34,12 @@ interface Props { const DisconnectFromParent = ({ node, onCurrentNodeChanged }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); - const { mutateAsync: disconnectNode } = useDeleteNodeConnectionMutation(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(undefined); + const { mutateAsync: disconnectNode, isError, isPending } = useDeleteNodeConnectionMutation(); const navigate = useNavigate(); const location = useLocation(); const qc = useQueryClient(); const onDisconnect = async (): Promise => { - setLoading(true); - setError(undefined); if ("connectionId" in node) { await disconnectNode( { @@ -62,7 +57,6 @@ const DisconnectFromParent = ({ node, onCurrentNodeChanged }: Props) => { navigate(location.pathname.split(node.id)[0], { replace: true }); onCurrentNodeChanged(undefined); }, - onError: () => setError(t("taxonomy.errorMessage")), }, ); } @@ -78,11 +72,11 @@ const DisconnectFromParent = ({ node, onCurrentNodeChanged }: Props) => { {t("taxonomy.publish.info")}
- - {error && {error}} + {isError && {t("taxonomy.errorMessage")}} ); }; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx index d512bb2beb..27c7c0c79d 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx @@ -33,6 +33,7 @@ const StatusIndicatorContent = styled("div", { base: { display: "flex", gap: "3xsmall", + alignItems: "center", }, }); @@ -154,7 +155,7 @@ const PublishChildNodeResources = ({ node }: Props) => { publishResources()}>{t("taxonomy.publish.button")} {showDisplay && ( - {done ? : } + {done ? : } {`${publishText} (${publishedCount}/${publishableCount})`} )} diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx index 0c6e941159..2cef85b268 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/SetResourcesPrimary.tsx @@ -6,10 +6,10 @@ * */ -import { useState } from "react"; import { useTranslation } from "react-i18next"; import { ErrorWarningLine } from "@ndla/icons/common"; -import { Button, Heading, MessageBox, Spinner, Text } from "@ndla/primitives"; +import { CheckLine } from "@ndla/icons/editor"; +import { Button, Heading, MessageBox, Text } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { Node } from "@ndla/types-taxonomy"; import { usePutResourcesPrimaryMutation } from "../../../../modules/nodes/nodeMutations"; @@ -28,6 +28,17 @@ const StyledButton = styled(Button, { alignSelf: "flex-end", }, }); +const StyledCheckLine = styled(CheckLine, { + base: { fill: "stroke.success" }, +}); + +const StatusIndicatorContent = styled("div", { + base: { + display: "flex", + gap: "3xsmall", + alignItems: "center", + }, +}); interface Props { node: Node; @@ -36,17 +47,11 @@ interface Props { const SetResourcesPrimary = ({ node, recursive = false }: Props) => { const { t } = useTranslation(); - const [error, setError] = useState(); - const { mutateAsync, isPending } = usePutResourcesPrimaryMutation(); + const { mutateAsync, isPending, isError, isSuccess } = usePutResourcesPrimaryMutation(); const { taxonomyVersion } = useTaxonomyVersion(); const setConnectedResourcesPrimary = async () => { - setError(undefined); - - await mutateAsync( - { taxonomyVersion, id: node.id, recursive }, - { onError: () => setError(t("taxonomy.resourcesPrimary.error")) }, - ); + await mutateAsync({ taxonomyVersion, id: node.id, recursive }); }; return ( @@ -58,11 +63,16 @@ const SetResourcesPrimary = ({ node, recursive = false }: Props) => { {recursive ? t("taxonomy.resourcesPrimary.recursiveText") : t("taxonomy.resourcesPrimary.text")} - + {t("alertModal.continue")} - {isPending && } - {error && {error}} + {isSuccess && ( + + + {t("taxonomy.resourcesPrimary.success")} + + )} + {isError && {t("taxonomy.resourcesPrimary.error")}} ); }; diff --git a/src/phrases/phrases-en.ts b/src/phrases/phrases-en.ts index f86eb5dd04..5293c2a7c5 100644 --- a/src/phrases/phrases-en.ts +++ b/src/phrases/phrases-en.ts @@ -1846,6 +1846,7 @@ const phrases = { buttonText: "Make resources primary", recursiveButtonText: "Make resources and sub resources primary", error: "An error occured", + success: "All resources have been converted to primary resources", }, goTo: "Open in structure editor", missingResourceType: "Missing resource type", diff --git a/src/phrases/phrases-nb.ts b/src/phrases/phrases-nb.ts index 1252dea36b..89663560db 100644 --- a/src/phrases/phrases-nb.ts +++ b/src/phrases/phrases-nb.ts @@ -1844,6 +1844,7 @@ const phrases = { buttonText: "Gjør alle ressurser om til primærkoblinger", recursiveButtonText: "Gjør alle ressurser og underressurser om til primærkoblinger", error: "En feil oppstod", + success: "Alle ressurser er gjort til primærkoblinger", }, goTo: "Åpne i stukturredigering", missingResourceType: "Mangler ressurstype", diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 0c04067f15..3fb738f6a3 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -1845,6 +1845,7 @@ const phrases = { buttonText: "Gjer alle ressursar om til primærkoblingar", recursiveButtonText: "Gjer alle ressursar og underressursar om til primærkoblingar", error: "Ein feil oppstod", + success: "Alle ressursar er gjort om til primærkoblingar", }, goTo: "Åpne i stukturredigering", missingResourceType: "Mangler ressurstype", From a97bb57e9c82d14909386287b5a64afd2dce1320 Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Mon, 18 Nov 2024 16:09:41 +0100 Subject: [PATCH 013/170] refactor: use panda in preview --- .../PreviewDraft/PreviewVersion.tsx | 69 +++++++++---------- src/components/PreviewDraft/styles.tsx | 17 +++-- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/components/PreviewDraft/PreviewVersion.tsx b/src/components/PreviewDraft/PreviewVersion.tsx index b21bb7eb07..9ea68b0438 100644 --- a/src/components/PreviewDraft/PreviewVersion.tsx +++ b/src/components/PreviewDraft/PreviewVersion.tsx @@ -11,11 +11,10 @@ import parse from "html-react-parser"; import { ReactNode, useMemo, useState } from "react"; import { renderToString } from "react-dom/server"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { colors, spacing } from "@ndla/core"; import { InformationOutline } from "@ndla/icons/common"; import { PageContent, SwitchControl, SwitchHiddenInput, SwitchLabel, SwitchRoot, SwitchThumb } from "@ndla/primitives"; import { MissingRouterContext } from "@ndla/safelink"; +import { styled } from "@ndla/styled-system/jsx"; import { IArticle } from "@ndla/types-backend/draft-api"; import { ArticleWrapper } from "@ndla/ui"; import { toFormArticle } from "./PreviewDraft"; @@ -34,41 +33,39 @@ export interface VersionPreviewProps { language: string; } -const SwitchWrapper = styled.div` - display: flex; - margin-right: ${spacing.xxlarge}; - justify-content: flex-end; - align-items: center; - gap: ${spacing.xsmall}; -`; +const SwitchWrapper = styled("div", { + base: { + display: "flex", + marginInlineEnd: "4xlarge", + justifyContent: "flex-end", + alignItems: "center", + gap: "3xsmall", + }, +}); -const TwoArticleWrapperWithDiff = styled(TwoArticleWrapper)` - del.diffmod, - ins.diffmod, - ins.mod { - background-color: ${colors.support.yellow}; - text-decoration: none; - display: inline-block; - } - - .diffins:has(img, div, figure, picture), - .diffmod:has(div, img, figure, picture) { - // Add some padding to show the diff outline on block elements - padding: 5px; - } - - .diffins { - background-color: ${colors.support.greenLight}; - text-decoration: none; - display: inline-block; - } - - del.diffdel { - background-color: ${colors.support.redLight}; - text-decoration: none; - display: inline-block; - } -`; +const TwoArticleWrapperWithDiff = styled(TwoArticleWrapper, { + base: { + "& del.diffmod, ins.diffmod, ins.mod": { + background: "surface.warning", + textDecoration: "none", + display: "inline-block", + }, + "& .diffins:has(img, div, figure, picture), .diffmod:has(div, img, figure, picture)": { + // Add some padding to show the diff outline on block elements + padding: "3xsmall", + }, + "& .diffins": { + background: "surface.successSubtle", + textDecoration: "none", + display: "inline-block", + }, + "& .diffdel": { + background: "surface.errorSubtle", + textDecoration: "none", + display: "inline-block", + }, + }, +}); const renderWithoutRouter = (node: ReactNode) => { return renderToString({node}); diff --git a/src/components/PreviewDraft/styles.tsx b/src/components/PreviewDraft/styles.tsx index 859a53b90b..79c421af7a 100644 --- a/src/components/PreviewDraft/styles.tsx +++ b/src/components/PreviewDraft/styles.tsx @@ -5,11 +5,14 @@ * LICENSE file in the root directory of this source tree. * */ -import styled from "@emotion/styled"; -export const TwoArticleWrapper = styled.div` - width: 100%; - max-width: 100%; - display: flex; - align-items: flex-start; -`; +import { styled } from "@ndla/styled-system/jsx"; + +export const TwoArticleWrapper = styled("div", { + base: { + width: "100%", + maxWidth: "100%", + display: "flex", + alignItems: "flex-start", + }, +}); From 8743dc894406cb50e36e32d4b589078a2d0869aa Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Mon, 18 Nov 2024 16:13:23 +0100 Subject: [PATCH 014/170] refactor: use panda in H5PElement --- src/components/H5PElement/H5PElement.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/components/H5PElement/H5PElement.tsx b/src/components/H5PElement/H5PElement.tsx index 127d1d30f4..fd82ac3529 100644 --- a/src/components/H5PElement/H5PElement.tsx +++ b/src/components/H5PElement/H5PElement.tsx @@ -8,21 +8,25 @@ import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; +import { styled } from "@ndla/styled-system/jsx"; import { ErrorMessage } from "@ndla/ui"; import { fetchH5PiframeUrl, editH5PiframeUrl, fetchH5PInfo } from "./h5pApi"; import handleError from "../../util/handleError"; -const FlexWrapper = styled.div` - display: flex; - flex: 1; - width: 100%; -`; +const FlexWrapper = styled("div", { + base: { + display: "flex", + flex: "1", + width: "100%", + }, +}); -const StyledIFrame = styled.iframe` - flex: 1; - overflow: hidden; -`; +const StyledIFrame = styled("iframe", { + base: { + flex: "1", + overflow: "hidden", + }, +}); export interface OnSelectObject { path?: string; From 11740d4cb76c94356718c9ca6afeb1f8f205464b Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Mon, 18 Nov 2024 16:19:54 +0100 Subject: [PATCH 015/170] refactor: use new icons in NodeIconType --- src/components/NodeIconType.tsx | 16 +++------------- src/phrases/phrases-en.ts | 1 + src/phrases/phrases-nb.ts | 1 + src/phrases/phrases-nn.ts | 1 + 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/components/NodeIconType.tsx b/src/components/NodeIconType.tsx index 745624eb27..8ce85ddcf1 100644 --- a/src/components/NodeIconType.tsx +++ b/src/components/NodeIconType.tsx @@ -6,23 +6,13 @@ * */ import { useTranslation } from "react-i18next"; -import styled from "@emotion/styled"; -import { colors } from "@ndla/core"; -import { MenuBook } from "@ndla/icons/action"; -import { Subject } from "@ndla/icons/contentType"; +import { BookOpenLine } from "@ndla/icons/common"; +import { FileListLine } from "@ndla/icons/editor"; import { Node } from "@ndla/types-taxonomy"; import { DiffType } from "../containers/NodeDiff/diffUtils"; import { SUBJECT_NODE } from "../modules/nodes/nodeApiTypes"; import { getNodeTypeFromNodeId } from "../modules/nodes/nodeUtil"; -const StyledMenuBook = styled(MenuBook)` - height: 31px; - width: 31px; - color: ${colors.brand.primary}; -`; - -const StyledSubject = StyledMenuBook.withComponent(Subject); - interface Props { node: DiffType | Node; } @@ -34,7 +24,7 @@ const NodeIconType = ({ node }: Props) => { ? getNodeTypeFromNodeId(node.id) : getNodeTypeFromNodeId(node.id.other ?? node.id.original!); - const Icon = nodeType === SUBJECT_NODE ? StyledMenuBook : StyledSubject; + const Icon = nodeType === SUBJECT_NODE ? BookOpenLine : FileListLine; return ; }; diff --git a/src/phrases/phrases-en.ts b/src/phrases/phrases-en.ts index 1edb3c8783..eaf89723ce 100644 --- a/src/phrases/phrases-en.ts +++ b/src/phrases/phrases-en.ts @@ -2029,6 +2029,7 @@ const phrases = { nodeTypeTooltips: { SUBJECT: "This is a subject", TOPIC: "This is a topic", + PROGRAMME: "This is a programme", }, fields: { id: { diff --git a/src/phrases/phrases-nb.ts b/src/phrases/phrases-nb.ts index 81a1147300..c6f21965e6 100644 --- a/src/phrases/phrases-nb.ts +++ b/src/phrases/phrases-nb.ts @@ -2027,6 +2027,7 @@ const phrases = { nodeTypeTooltips: { SUBJECT: "Dette er et fag", TOPIC: "Dette er et emne", + PROGRAMME: "Dette er et utdanningsprogram", }, fields: { id: { diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 0aed726c76..fc4d22d037 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -2028,6 +2028,7 @@ const phrases = { nodeTypeTooltips: { SUBJECT: "Dette er eit fag", TOPIC: "Dette er eit emne", + PROGRAMME: "Dette er eit utdanningsprogram", }, fields: { id: { From 5612205d6e734d83c4f7c4b9af15fc811b290d71 Mon Sep 17 00:00:00 2001 From: Gunnar Velle Date: Tue, 19 Nov 2024 07:16:59 +0100 Subject: [PATCH 016/170] Fix delete button --- src/components/HeaderWithLanguage/DeleteLanguageVersion.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/HeaderWithLanguage/DeleteLanguageVersion.tsx b/src/components/HeaderWithLanguage/DeleteLanguageVersion.tsx index b97d1bec05..ac6fe11d3f 100644 --- a/src/components/HeaderWithLanguage/DeleteLanguageVersion.tsx +++ b/src/components/HeaderWithLanguage/DeleteLanguageVersion.tsx @@ -135,7 +135,11 @@ const DeleteLanguageVersion = ({ id, language, supportedLanguages, type, disable - +
From f0a061f8131b008e20a478f0c105fc7af0b7476b Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Mon, 18 Nov 2024 08:50:00 +0100 Subject: [PATCH 017/170] Rename component. Remove unecessary div-wrappers. Simplify handleSubmit. Update dialog position. Update select widths. --- src/components/FormWrapper.tsx | 2 +- .../StructurePage/folderComponents/SettingsMenu.tsx | 2 +- .../components/MenuItemCustomField.tsx | 4 ++-- .../{ConstantMetaField.tsx => SubjectForwardField.tsx} | 10 ++++------ .../subjectMenuOptions/TaxonomyMetadataDropdown.tsx | 5 ++++- .../topicMenuOptions/CopyNodeResources.tsx | 5 ++--- .../topicMenuOptions/PublishChildNodeResources.tsx | 4 ++-- .../topicMenuOptions/SwapTopicArticle.tsx | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) rename src/containers/StructurePage/folderComponents/sharedMenuOptions/components/{ConstantMetaField.tsx => SubjectForwardField.tsx} (88%) diff --git a/src/components/FormWrapper.tsx b/src/components/FormWrapper.tsx index 5f7b2df9a1..68eb9d2e4f 100644 --- a/src/components/FormWrapper.tsx +++ b/src/components/FormWrapper.tsx @@ -23,7 +23,7 @@ const StyledForm = styled(Form, { const FormWrapper = ({ inModal, children, ...rest }: Props) => { if (inModal) { - return {children}; + return {children}; } return
{children}
; }; diff --git a/src/containers/StructurePage/folderComponents/SettingsMenu.tsx b/src/containers/StructurePage/folderComponents/SettingsMenu.tsx index 5172e3ae45..970b3f11d8 100644 --- a/src/containers/StructurePage/folderComponents/SettingsMenu.tsx +++ b/src/containers/StructurePage/folderComponents/SettingsMenu.tsx @@ -41,7 +41,7 @@ const SettingsMenu = ({ node, rootNodeId, onCurrentNodeChanged, nodeChildren }: const nodeType = getNodeTypeFromNodeId(node.id); return ( - + { - diff --git a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/SubjectForwardField.tsx similarity index 88% rename from src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx rename to src/containers/StructurePage/folderComponents/sharedMenuOptions/components/SubjectForwardField.tsx index fb2a106a87..032d051af5 100644 --- a/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/ConstantMetaField.tsx +++ b/src/containers/StructurePage/folderComponents/sharedMenuOptions/components/SubjectForwardField.tsx @@ -11,7 +11,7 @@ import { useTranslation } from "react-i18next"; import { FieldLabel } from "@ark-ui/react"; import { DeleteBinLine } from "@ndla/icons/action"; import { CheckLine } from "@ndla/icons/editor"; -import { FieldInput, FieldRoot, IconButton, Input } from "@ndla/primitives"; +import { FieldInput, FieldRoot, IconButton } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { Metadata } from "@ndla/types-taxonomy"; import { TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID } from "../../../../../constants"; @@ -43,17 +43,15 @@ interface Props { initialVal?: string; } -const ConstantMetaField = ({ onSubmit, initialVal = "" }: Props) => { +const SubjectForwardField = ({ onSubmit, initialVal = "" }: Props) => { const { t } = useTranslation(); const [currentVal, setCurrentVal] = useState(); const handleSubmit = () => { - const newPair: Record = {}; if (initialVal !== currentVal && !!currentVal) { - newPair[TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID] = currentVal; onSubmit((prevState: Metadata["customFields"]) => ({ ...prevState, - ...newPair, + [TAXONOMY_CUSTOM_FIELD_SUBJECT_OLD_SUBJECT_ID]: currentVal, })); } }; @@ -97,4 +95,4 @@ const ConstantMetaField = ({ onSubmit, initialVal = "" }: Props) => { ); }; -export default ConstantMetaField; +export default SubjectForwardField; diff --git a/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx b/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx index e04bca014b..6dd0786e12 100644 --- a/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx +++ b/src/containers/StructurePage/folderComponents/subjectMenuOptions/TaxonomyMetadataDropdown.tsx @@ -20,7 +20,10 @@ import { styled } from "@ndla/styled-system/jsx"; import { GenericSelectItem, GenericSelectTrigger } from "../../../../components/abstractions/Select"; const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { - base: { flexGrow: "1" }, + base: { + flexGrow: "1", + width: "xxlarge", + }, }); interface Option { key: string; diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx index 9b9b6d075c..2850d6d41a 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx @@ -180,13 +180,12 @@ const CopyNodeResources = ({ currentNode, nodeType, type }: Props) => { {`${prefixText} (${count}/${totalAmount})`} )} - {failedResources.length > 0 && ( {t(`taxonomy.${type}.error`)} -
+ <> {failedResources.map((res, index) => (
{ />
))} -
+
)} diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx index 27c7c0c79d..48fc3d8359 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx @@ -164,7 +164,7 @@ const PublishChildNodeResources = ({ node }: Props) => { {t("taxonomy.publish.error")} -
+ <> {failedResources.map((res, index) => (
{ />
))} -
+
)} diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx index 591eabe9d1..678f8d66ec 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/SwapTopicArticle.tsx @@ -117,7 +117,7 @@ const SwapTopicArticle = ({ node, rootNodeId }: Props) => { isFetching={searchQuery.isFetching} /> -
+ <> {putNodeMutation.isPending && } {putNodeMutation.isSuccess && ( @@ -130,7 +130,7 @@ const SwapTopicArticle = ({ node, rootNodeId }: Props) => { {error} )} -
+ ); }; From 813e65301a5502791af5d2944cff2573b010cbd3 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Tue, 19 Nov 2024 08:37:19 +0100 Subject: [PATCH 018/170] Update nn translations --- src/phrases/phrases-nn.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/phrases/phrases-nn.ts b/src/phrases/phrases-nn.ts index 3fb738f6a3..f1accc3e88 100644 --- a/src/phrases/phrases-nn.ts +++ b/src/phrases/phrases-nn.ts @@ -1442,7 +1442,7 @@ const phrases = { multipleFiles: "Du kan laste opp forskjellige lydfiler for kvart språk.", changeFile: "Fjerning og endring av eit språk vil ikkje påverke dei andre språka.", newLanguage: "Ved oppretting av eit nytt språk vil ei lydfil fra eit eksisterande språk foreslås.", - deleteFiles: "Ei lydfil slettes berre når den ikkje lenger brukes i eit språk.", + deleteFiles: "Ei lydfil slettast berre når den ikkje lenger brukes i eit språk.", }, modal: { header: "Lydfiler", @@ -1699,7 +1699,7 @@ const phrases = { currentVersion: "Noverande versjon", deleteNode: "Slett node", deleteResource: "Slett ressurs", - deleteDisabled: "Noder med barn kan ikkje slettes", + deleteDisabled: "Noder med barn kan ikkje slettast", confirmDelete: "Er du sikker på at du vil slette denne noden?", version: "Versjon", createResource: "Opprett ny ressurs", @@ -1948,10 +1948,10 @@ const phrases = { title: "Taksonomiversjonar", publishedVersion: "Publisert versjon", otherVersions: "Øvrige versjonar", - deleteLocked: "Denne versjonen kan ikkje slettes fordi den er låst", - deletePublished: "Denne versjonen kan ikkje slettes fordi den er publisert", + deleteLocked: "Denne versjonen kan ikkje slettast fordi den er låst", + deletePublished: "Denne versjonen kan ikkje slettast fordi den er publisert", delete: "Slett versjon", - locked: "Denne versjonen er låst og kan ikkje slettes", + locked: "Denne versjonen er låst og kan ikkje slettast", status: { PUBLISHED: "Publisert", ARCHIVED: "Arkivert", @@ -1990,7 +1990,7 @@ const phrases = { }, locked: { title: "Låst", - subTitle: "Lås versjonen så den ikkje kan slettes", + subTitle: "Lås versjonen så den ikkje kan slettast", locked: "Låst", unlocked: "Ulåst", }, From d79d46929ef7ae6fff7e369c21551f616afcfc58 Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Tue, 19 Nov 2024 10:52:40 +0100 Subject: [PATCH 019/170] Remove ResourceItemLink --- .../topicMenuOptions/CopyNodeResources.tsx | 34 ++++++--- .../PublishChildNodeResources.tsx | 35 ++++++--- .../resourceComponents/ResourceItemLink.tsx | 75 ------------------- 3 files changed, 46 insertions(+), 98 deletions(-) delete mode 100644 src/containers/StructurePage/resourceComponents/ResourceItemLink.tsx diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx index 2850d6d41a..5b59f6146c 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx @@ -6,20 +6,22 @@ * */ -import { useState } from "react"; +import { Fragment, useState } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; import { ErrorWarningLine } from "@ndla/icons/common"; import { CheckLine } from "@ndla/icons/editor"; import { Text, Spinner, MessageBox } from "@ndla/primitives"; +import { SafeLink } from "@ndla/safelink"; import { styled } from "@ndla/styled-system/jsx"; import { Node, NodeChild, NodeType } from "@ndla/types-taxonomy"; import { cloneDraft } from "../../../../modules/draft/draftApi"; import { learningpathCopy } from "../../../../modules/learningpath/learningpathApi"; import { cloneNode, fetchNodeResources, postResourceForNode } from "../../../../modules/nodes/nodeApi"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; +import { routes } from "../../../../util/routeHelpers"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; +import { linkRecipe } from "../../resourceComponents/Resource"; import NodeSearchDropdown from "../sharedMenuOptions/components/NodeSearchDropdown"; type ActionType = "copyResources" | "cloneResources"; @@ -186,15 +188,25 @@ const CopyNodeResources = ({ currentNode, nodeType, type }: Props) => { {t(`taxonomy.${type}.error`)} <> - {failedResources.map((res, index) => ( -
- -
- ))} + {failedResources.map((res, index) => { + const numericId = parseInt(res.contentUri?.split(":").pop() ?? ""); + return ( + + {numericId ? ( + + {res.name} + + ) : ( + {res.name} + )} + + ); + })}
diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx index 48fc3d8359..81cadcc78f 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/PublishChildNodeResources.tsx @@ -7,12 +7,13 @@ */ import partition from "lodash/partition"; -import { useState } from "react"; +import { Fragment, useState } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; import { ErrorWarningLine } from "@ndla/icons/common"; import { CheckLine } from "@ndla/icons/editor"; import { Button, Heading, MessageBox, Spinner, Text } from "@ndla/primitives"; +import { SafeLink } from "@ndla/safelink"; import { styled } from "@ndla/styled-system/jsx"; import { IArticle } from "@ndla/types-backend/draft-api"; import { ILearningPathV2 } from "@ndla/types-backend/learningpath-api"; @@ -22,8 +23,9 @@ import { fetchDrafts, updateStatusDraft } from "../../../../modules/draft/draftA import { fetchLearningpaths, updateStatusLearningpath } from "../../../../modules/learningpath/learningpathApi"; import { fetchNodeResources } from "../../../../modules/nodes/nodeApi"; import { RESOURCE_META } from "../../../../queryKeys"; +import { routes } from "../../../../util/routeHelpers"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; -import ResourceItemLink from "../../resourceComponents/ResourceItemLink"; +import { linkRecipe } from "../../resourceComponents/Resource"; interface Props { node: Node; @@ -165,16 +167,25 @@ const PublishChildNodeResources = ({ node }: Props) => { {t("taxonomy.publish.error")} <> - {failedResources.map((res, index) => ( -
- -
- ))} + {failedResources.map((res, index) => { + const numericId = parseInt(res.contentUri?.split(":").pop() ?? ""); + return ( + + {numericId ? ( + + {res.name} + + ) : ( + {res.name} + )} + + ); + })}
diff --git a/src/containers/StructurePage/resourceComponents/ResourceItemLink.tsx b/src/containers/StructurePage/resourceComponents/ResourceItemLink.tsx deleted file mode 100644 index 79e1f90bde..0000000000 --- a/src/containers/StructurePage/resourceComponents/ResourceItemLink.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2019-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import styled from "@emotion/styled"; -import { colors, fonts, mq, breakpoints } from "@ndla/core"; -import { constants } from "@ndla/ui"; -import { toEditArticle, toLearningpathFull } from "../../../util/routeHelpers"; - -const { contentTypes } = constants; - -type FontSizeType = "small" | "medium"; - -const StyledH1 = styled.h1<{ isVisible?: boolean; size?: FontSizeType }>` - font-style: ${(props) => !props.isVisible && "italic"}; - color: ${(props) => (!props.isVisible ? colors.brand.grey : colors.brand.primary)}; - text-transform: none; - letter-spacing: 0; - margin: 0; - display: inline; - ${(props) => fonts.sizes(props.size === "small" ? "16px" : "18px")}; - font-weight: ${fonts.weight.normal}; - - ${mq.range({ from: breakpoints.desktop })} { - ${(props) => fonts.sizes(props.size === "small" ? "18px" : "20px")}; - } -`; - -interface Props { - contentType?: string; - contentUri?: string; - name?: string; - isVisible?: boolean; - size?: FontSizeType; -} - -const ResourceItemLink = ({ contentType, contentUri, name, isVisible = true, size = "medium" }: Props) => { - const { i18n } = useTranslation(); - const linkTo = contentUri && contentUri.split(":").pop(); - - if (linkTo) { - if (contentType === contentTypes.LEARNING_PATH) { - const linkProps = { - href: toLearningpathFull(parseInt(linkTo), i18n.language), - target: "_blank", - rel: "noopener noreferrer", - }; - return ( - - {name} - - ); - } - return ( - - - {name} - - - ); - } - return ( - - {name} - - ); -}; - -export default ResourceItemLink; From 08731fa0a22e873c6b172eacc23c22e358896884 Mon Sep 17 00:00:00 2001 From: Gunnar Velle Date: Tue, 19 Nov 2024 12:36:38 +0100 Subject: [PATCH 020/170] Fix h5p-resizing --- src/components/SlateEditor/RichTextEditor.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/SlateEditor/RichTextEditor.tsx b/src/components/SlateEditor/RichTextEditor.tsx index 13a3555486..803812f281 100644 --- a/src/components/SlateEditor/RichTextEditor.tsx +++ b/src/components/SlateEditor/RichTextEditor.tsx @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * */ + import { useFormikContext } from "formik"; import isEqual from "lodash/isEqual"; import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from "react"; @@ -14,6 +15,7 @@ import { Slate, Editable, withReact, RenderElementProps, RenderLeafProps, ReactE import { EditableProps } from "slate-react/dist/components/editable"; import { Spinner } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; +import "../DisplayEmbed/helpers/h5pResizer"; import { ArticleLanguageProvider } from "./ArticleLanguageProvider"; import { SlatePlugin } from "./interfaces"; import { Action, commonActions } from "./plugins/blockPicker/actions"; From bc22d59145d450b2dc63f36a3dc933d33c38db3e Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Tue, 19 Nov 2024 15:04:42 +0100 Subject: [PATCH 021/170] Also support failed learning paths --- .../topicMenuOptions/CopyNodeResources.tsx | 8 ++++++-- .../topicMenuOptions/PublishChildNodeResources.tsx | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx index 5b59f6146c..417719bb31 100644 --- a/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx +++ b/src/containers/StructurePage/folderComponents/topicMenuOptions/CopyNodeResources.tsx @@ -19,7 +19,7 @@ import { cloneDraft } from "../../../../modules/draft/draftApi"; import { learningpathCopy } from "../../../../modules/learningpath/learningpathApi"; import { cloneNode, fetchNodeResources, postResourceForNode } from "../../../../modules/nodes/nodeApi"; import { nodeQueryKeys } from "../../../../modules/nodes/nodeQueries"; -import { routes } from "../../../../util/routeHelpers"; +import { routes, toLearningpathFull } from "../../../../util/routeHelpers"; import { useTaxonomyVersion } from "../../../StructureVersion/TaxonomyVersionProvider"; import { linkRecipe } from "../../resourceComponents/Resource"; import NodeSearchDropdown from "../sharedMenuOptions/components/NodeSearchDropdown"; @@ -194,7 +194,11 @@ const CopyNodeResources = ({ currentNode, nodeType, type }: Props) => { {numericId ? ( { {numericId ? ( Date: Tue, 19 Nov 2024 14:33:02 +0100 Subject: [PATCH 022/170] Update delete node translations --- .../SettingsMenuDropdownType.tsx | 29 +++++++++++++++--- .../sharedMenuOptions/DeleteNode.tsx | 30 +++++++++++++++++-- .../resourceComponents/ResourceItems.tsx | 4 +-- src/containers/StructurePage/utils.ts | 9 ++++++ src/phrases/phrases-en.ts | 14 ++++++--- src/phrases/phrases-nb.ts | 14 ++++++--- src/phrases/phrases-nn.ts | 15 +++++++--- 7 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 src/containers/StructurePage/utils.ts diff --git a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx index 71e5f44dcf..d57b06dd2f 100644 --- a/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx +++ b/src/containers/StructurePage/folderComponents/SettingsMenuDropdownType.tsx @@ -81,7 +81,13 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node })} {t("metadata.changeVisibility")} - {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + {isTaxonomyAdmin && ( + + {t("taxonomy.delete.deleteNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} + + )} {isTaxonomyAdmin && ( @@ -104,9 +110,10 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node {isTaxonomyAdmin && ( - + {isTaxonomyAdmin && {t("taxonomy.grepCodes.edit")}} - {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + {isTaxonomyAdmin && ( + + {t("taxonomy.delete.deleteNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} + + )} {isTaxonomyAdmin && ( @@ -184,6 +197,7 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node )} - {isTaxonomyAdmin && {t("taxonomy.deleteNode")}} + {isTaxonomyAdmin && ( + + {t("taxonomy.delete.deleteNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} + + )} {isTaxonomyAdmin && ( @@ -262,6 +282,7 @@ const SettingsMenuDropdownType = ({ rootNodeId, node, onCurrentNodeChanged, node = { + SUBJECT: "taxonomy.delete.topic", + TOPIC: "taxonomy.delete.subTopic", + PROGRAMME: "taxonomy.delete.child", +}; interface Props { node: Node | NodeChild; + nodeType: NodeType; nodeChildren: Node[]; onCurrentNodeChanged: (node?: Node) => void; rootNodeId?: string; } -const DeleteNode = ({ node, nodeChildren, onCurrentNodeChanged, rootNodeId }: Props) => { +const DeleteNode = ({ node, nodeType, nodeChildren, onCurrentNodeChanged, rootNodeId }: Props) => { const { t, i18n } = useTranslation(); const { taxonomyVersion } = useTaxonomyVersion(); const [loading, setLoading] = useState(false); @@ -90,11 +101,24 @@ const DeleteNode = ({ node, nodeChildren, onCurrentNodeChanged, rootNodeId }: Pr return ( -

{t("taxonomy.deleteNode")}

+

+ {t("taxonomy.delete.deleteNode", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + })} +

- {disabled ? t("taxonomy.deleteDisabled") : t("taxonomy.confirmDelete")} + + {disabled + ? capitalizeFirstLetter( + t("taxonomy.delete.deleteDisabled", { + nodeType: t(`taxonomy.nodeType.${nodeType}`), + childNode: t(childTranslation[nodeType]), + }), + ) + : t("taxonomy.delete.confirmDelete", { nodeType: t(`taxonomy.${node.nodeType}`) })} + + ); + + const secondaryButtons: SecondaryButton[] = [ + { + label: t("form.saveAsNewVersion"), + value: "saveAsNew", + disable: isSaving, + }, + { + label: t("form.save"), + value: "save", + disable: disabledButton, + }, + ]; + + const isDisabled = secondaryButtons.some((button) => !button.disable) ? hasErrors : true; return ( - <> - - { - const saveAsNewVersion = value === "saveAsNew"; - onClick(saveAsNewVersion); - }} - mainButton={{ value: "save", label: "" }} - secondaryButtons={ - hideSecondaryButton - ? [] - : [ - { - label: t("form.saveAsNewVersion"), - value: "saveAsNew", - enable: !isSaving, - }, - { - label: t("form.save"), - value: "save", - enable: !disabledButton, - }, - ] - } - large - {...rest} - > - - {t(`form.${modifier}`)} - {showSaved && } - - - - + + + {showSaved && } + {buttonSaveText} + + setOpen(details.open)} + positioning={{ + placement: "top", + }} + > + + + + + + + + {secondaryButtons.map((button) => ( + + + + ))} + + + + ); }; diff --git a/src/components/SlateEditor/EditorFooter.tsx b/src/components/SlateEditor/EditorFooter.tsx index 47bbeea218..ea50cd8643 100644 --- a/src/components/SlateEditor/EditorFooter.tsx +++ b/src/components/SlateEditor/EditorFooter.tsx @@ -226,14 +226,12 @@ function EditorFooter({
)} @@ -288,14 +286,12 @@ function EditorFooter({ /> From 60358bd21c7f4b6881a78af50f7ed3be2f5a1e4f Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Thu, 21 Nov 2024 11:26:36 +0100 Subject: [PATCH 029/170] playwright tests --- e2e/specs/grid.spec.ts | 11 ++++++----- src/components/SlateEditor/plugins/grid/GridForm.tsx | 7 ++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/e2e/specs/grid.spec.ts b/e2e/specs/grid.spec.ts index 3106811e50..10185634f1 100644 --- a/e2e/specs/grid.spec.ts +++ b/e2e/specs/grid.spec.ts @@ -21,29 +21,30 @@ test("can select multiple different sizes", async ({ page }) => { expect(await page.getByTestId("slate-grid-cell").count()).toEqual(2); await page.getByTestId("edit-grid-button").click(); await page.getByRole("radiogroup").getByText("4").click(); - await page.getByRole("button", { name: "Lagre", exact: true }).click(); + await page.getByTestId("grid-form-save-button").click(); expect(await page.getByTestId("slate-grid-cell").count()).toEqual(4); await page.getByTestId("edit-grid-button").click(); await page.getByRole("radiogroup").getByText("2x2").click(); - await page.getByRole("button", { name: "Lagre", exact: true }).click(); + await page.getByTestId("grid-form-save-button").click(); expect(await page.getByTestId("slate-grid-cell").count()).toEqual(4); await page.getByTestId("edit-grid-button").click(); await page.getByRole("radiogroup").getByText("2", { exact: true }).click(); - await page.getByRole("button", { name: "Lagre", exact: true }).click(); + await page.getByTestId("grid-form-save-button").click(); expect(await page.getByTestId("slate-grid-cell").count()).toEqual(2); }); test("can change background color", async ({ page }) => { await page.getByTestId("edit-grid-button").click(); await page.getByText("Hvit").click(); - await page.getByRole("button", { name: "Lagre", exact: true }).click(); + await page.getByTestId("grid-form-save-button").click(); }); test("can set border", async ({ page }) => { await page.getByTestId("edit-grid-button").click(); let checkbox = page.locator('[data-scope="checkbox"][data-part="root"]'); await checkbox.click(); - await page.getByRole("button", { name: "Lagre", exact: true }).click(); + await page.getByTestId("grid-form-save-button").click(); + await page.getByTestId("edit-grid-button").click(); checkbox = page.locator('[data-scope="checkbox"][data-part="root"][data-state="checked"]'); await expect(checkbox).toBeVisible(); diff --git a/src/components/SlateEditor/plugins/grid/GridForm.tsx b/src/components/SlateEditor/plugins/grid/GridForm.tsx index 119bf9b2d9..ac7e4b16b0 100644 --- a/src/components/SlateEditor/plugins/grid/GridForm.tsx +++ b/src/components/SlateEditor/plugins/grid/GridForm.tsx @@ -176,7 +176,12 @@ const GridForm = ({ initialData, onSave, onCancel }: Props) => { - From 77f0502a813ec845867f99f773a14ff4f406db9c Mon Sep 17 00:00:00 2001 From: Katrine Wist Date: Thu, 21 Nov 2024 09:27:16 +0100 Subject: [PATCH 030/170] Refactor breadcrumb to new components + panda --- src/components/Taxonomy/Breadcrumb.tsx | 78 +++++++++++++++----------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/src/components/Taxonomy/Breadcrumb.tsx b/src/components/Taxonomy/Breadcrumb.tsx index 9d31264b73..a74e1351ec 100644 --- a/src/components/Taxonomy/Breadcrumb.tsx +++ b/src/components/Taxonomy/Breadcrumb.tsx @@ -5,39 +5,53 @@ * LICENSE file in the root directory of this source tree. * */ -import { Fragment, useMemo } from "react"; -import styled from "@emotion/styled"; -import { colors, fonts } from "@ndla/core"; +import { useMemo } from "react"; import { ArrowRightShortLine } from "@ndla/icons/common"; import { SafeLink } from "@ndla/safelink"; +import { styled } from "@ndla/styled-system/jsx"; import { Node } from "@ndla/types-taxonomy"; import { MinimalNodeChild } from "../../containers/ArticlePage/LearningResourcePage/components/LearningResourceTaxonomy"; -interface Props { - error?: boolean; - node: Node | MinimalNodeChild; -} +const StyledSafeLink = styled(SafeLink, { + base: { + color: "text.default", + textDecoration: "underline", + _hover: { + textDecoration: "none", + }, + }, + variants: { + visible: { + false: { + fontStyle: "italic", + color: "text.subtle", + }, + }, + }, +}); -const StyledBreadCrumb = styled.div` - flex-grow: 1; - span:last-of-type { - font-weight: ${fonts.weight.semibold}; - } -`; +const StyledList = styled("ol", { + base: { + display: "flex", + flexWrap: "wrap", + alignItems: "center", + listStyle: "none", + }, +}); -const StyledLink = styled(SafeLink)` - color: ${colors.brand.primary}; - &[data-visible="false"] { - font-style: italic; - color: ${colors.brand.grey}; - } -`; +const StyledListItem = styled("li", { + base: { + _lastOfType: { + fontWeight: "semibold", + }, + }, +}); -const StyledSpan = styled.span` - white-space: "nowrap"; -`; +interface Props { + node: Node | MinimalNodeChild; +} -const Breadcrumb = ({ node, error }: Props) => { +const Breadcrumb = ({ node }: Props) => { let url = "/structure"; const crumbs = useMemo(() => { @@ -54,21 +68,19 @@ const Breadcrumb = ({ node, error }: Props) => { }, [node.breadcrumbs, node.context, node.id, node.nodeType]); return ( - + {crumbs.map((crumb, index) => { url = `${url}/${crumb.id}`; return ( - - - - {crumb.name} - - + + + {crumb.name} + {index + 1 !== crumbs.length && } - + ); })} - + ); }; From 54076932d1046408048f40da124be5f7e920e791 Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Thu, 21 Nov 2024 11:46:25 +0100 Subject: [PATCH 031/170] chore: bump ndla packages --- package.json | 16 +- src/components/Form/GenericSearchCombobox.tsx | 41 +- src/components/Form/SearchTagsContent.tsx | 10 +- .../HeaderLanguagePicker.tsx | 18 +- src/components/SaveMultiButton.tsx | 22 +- .../plugins/audio/AudioEmbedForm.tsx | 17 +- .../plugins/codeBlock/CodeBlockEditor.tsx | 17 +- .../toolbar/ToolbarLanguageOptions.tsx | 26 +- .../plugins/toolbar/ToolbarTextOptions.tsx | 40 +- .../plugins/toolbar/ToolbarToggle.tsx | 11 +- .../Taxonomy/OptGroupVersionSelector.tsx | 37 +- .../App/components/FooterWrapper.tsx | 18 +- .../components/ResourceTypeSelect.tsx | 18 +- src/containers/FormikForm/GrepCodesField.tsx | 27 +- .../components/ContributorsField.tsx | 17 +- .../FormikForm/components/LicenseField.tsx | 17 +- .../FormikForm/components/PrioritySelect.tsx | 18 +- .../components/ResponsibleSelect.tsx | 26 +- .../FormikForm/components/StatusSelect.tsx | 18 +- .../GlossPage/components/ExampleField.tsx | 17 +- .../GlossPage/components/GlossDataSection.tsx | 35 +- .../Masthead/components/MastheadSearch.tsx | 31 +- .../__snapshots__/Messages-test.tsx.snap | 2 +- src/containers/NodeDiff/DiffOptions.tsx | 20 +- .../components/results/SearchListOptions.tsx | 18 +- .../SearchPage/components/sort/SearchSort.tsx | 34 +- .../subjectMenuOptions/AddNodeTranslation.tsx | 17 +- .../TaxonomyMetadataDropdown.tsx | 27 +- .../plannedResource/PlannedResourceForm.tsx | 17 +- .../plannedResource/PlannedResourceSelect.tsx | 21 +- .../components/worklist/PageSizeSelect.tsx | 23 +- .../components/worklist/SubjectCombobox.tsx | 41 +- yarn.lock | 619 ++++++++++++++---- 33 files changed, 810 insertions(+), 526 deletions(-) diff --git a/package.json b/package.json index 7e9d5373d3..452deb1333 100644 --- a/package.json +++ b/package.json @@ -86,21 +86,21 @@ "@fontsource/source-code-pro": "^4.5.9", "@fontsource/source-sans-pro": "^4.5.9", "@fontsource/source-serif-pro": "^4.5.7", - "@ndla/article-converter": "^10.0.73-alpha.0", - "@ndla/audio-search": "^7.0.60-alpha.0", - "@ndla/button": "^15.0.44-alpha.0", + "@ndla/article-converter": "^10.0.74-alpha.0", + "@ndla/audio-search": "^7.0.61-alpha.0", "@ndla/error-reporter": "^2.0.4", "@ndla/hooks": "^2.1.9", "@ndla/icons": "^8.0.43-alpha.0", - "@ndla/image-search": "^11.0.62-alpha.0", + "@ndla/image-search": "^11.0.63-alpha.0", "@ndla/licenses": "^8.0.3-alpha.0", - "@ndla/primitives": "^1.0.54-alpha.0", - "@ndla/safelink": "^7.0.55-alpha.0", + "@ndla/primitives": "^1.0.55-alpha.0", + "@ndla/safelink": "^7.0.56-alpha.0", "@ndla/styled-system": "^0.0.27", "@ndla/tracker": "^5.0.11-alpha.0", - "@ndla/ui": "^56.0.70-alpha.0", + "@ndla/ui": "^56.0.71-alpha.0", "@ndla/util": "^5.0.0-alpha.0", - "@ndla/video-search": "^8.0.59-alpha.0", + "@ndla/video-search": "^8.0.60-alpha.0", + "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-popover": "^1.0.3", "@radix-ui/react-portal": "^1.0.3", "@radix-ui/react-toolbar": "^1.0.4", diff --git a/src/components/Form/GenericSearchCombobox.tsx b/src/components/Form/GenericSearchCombobox.tsx index 4b035783bc..d37822fbfd 100644 --- a/src/components/Form/GenericSearchCombobox.tsx +++ b/src/components/Form/GenericSearchCombobox.tsx @@ -14,7 +14,6 @@ import { ComboboxContent, ComboboxItem, ComboboxList, - ComboboxPositioner, ComboboxRoot, ComboboxRootProps, PaginationRootProps, @@ -98,27 +97,25 @@ export const GenericSearchCombobox = ({ {...props} > {children} - - - - {collection.items.map((item) => ( - - {renderItem(item)} - - ))} - - {isSuccess && {t("dropdown.numberHits", { hits: paginationData?.totalCount ?? 0 })}} - {!!paginationData && paginationData.totalCount > paginationData.pageSize && ( - - )} - - + + + {collection.items.map((item) => ( + + {renderItem(item)} + + ))} + + {isSuccess && {t("dropdown.numberHits", { hits: paginationData?.totalCount ?? 0 })}} + {!!paginationData && paginationData.totalCount > paginationData.pageSize && ( + + )} + ); }; diff --git a/src/components/Form/SearchTagsContent.tsx b/src/components/Form/SearchTagsContent.tsx index 0c0f86a4c0..0dc28af82b 100644 --- a/src/components/Form/SearchTagsContent.tsx +++ b/src/components/Form/SearchTagsContent.tsx @@ -8,7 +8,7 @@ import { forwardRef } from "react"; import { useTranslation } from "react-i18next"; -import { ComboboxContent, ComboboxContentProps, ComboboxPositioner, Spinner, Text } from "@ndla/primitives"; +import { ComboboxContent, ComboboxContentProps, Spinner, Text } from "@ndla/primitives"; interface Props extends ComboboxContentProps { isFetching: boolean; @@ -18,10 +18,8 @@ interface Props extends ComboboxContentProps { export const SearchTagsContent = forwardRef(({ isFetching, hits, children, ...props }, ref) => { const { t } = useTranslation(); return ( - - - {isFetching ? : hits ? children : {t("dropdown.numberHits", { hits: 0 })}} - - + + {isFetching ? : hits ? children : {t("dropdown.numberHits", { hits: 0 })}} + ); }); diff --git a/src/components/HeaderWithLanguage/HeaderLanguagePicker.tsx b/src/components/HeaderWithLanguage/HeaderLanguagePicker.tsx index ac577bdae9..8da9e62fcc 100644 --- a/src/components/HeaderWithLanguage/HeaderLanguagePicker.tsx +++ b/src/components/HeaderWithLanguage/HeaderLanguagePicker.tsx @@ -8,7 +8,7 @@ import { useTranslation } from "react-i18next"; import { AddLine } from "@ndla/icons/action"; -import { Button, MenuContent, MenuItem, MenuPositioner, MenuRoot, MenuTrigger } from "@ndla/primitives"; +import { Button, MenuContent, MenuItem, MenuRoot, MenuTrigger } from "@ndla/primitives"; import { SafeLink } from "@ndla/safelink"; const LanguagePicker = ({ id, emptyLanguages, editUrl }: Props) => { @@ -20,15 +20,13 @@ const LanguagePicker = ({ id, emptyLanguages, editUrl }: Props) => { {t("form.variant.create")} - - - {emptyLanguages.map((language) => ( - - {language.title} - - ))} - - + + {emptyLanguages.map((language) => ( + + {language.title} + + ))} + ); }; diff --git a/src/components/SaveMultiButton.tsx b/src/components/SaveMultiButton.tsx index e7439e8828..7718cb503f 100644 --- a/src/components/SaveMultiButton.tsx +++ b/src/components/SaveMultiButton.tsx @@ -10,7 +10,7 @@ import { useState, MouseEvent } from "react"; import { useTranslation } from "react-i18next"; import { ArrowDownShortLine } from "@ndla/icons/common"; import { CheckLine } from "@ndla/icons/editor"; -import { Button, IconButton, MenuContent, MenuItem, MenuPositioner, MenuRoot, MenuTrigger } from "@ndla/primitives"; +import { Button, IconButton, MenuContent, MenuItem, MenuRoot, MenuTrigger } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { SAVE_BUTTON_ID } from "../constants"; @@ -125,17 +125,15 @@ const SaveMultiButton = ({ isSaving, showSaved, formIsDirty, hasErrors, onClick, - - - {secondaryButtons.map((button) => ( - - - - ))} - - + + {secondaryButtons.map((button) => ( + + + + ))} + ); diff --git a/src/components/SlateEditor/plugins/audio/AudioEmbedForm.tsx b/src/components/SlateEditor/plugins/audio/AudioEmbedForm.tsx index 062831ac9c..113feca8c9 100644 --- a/src/components/SlateEditor/plugins/audio/AudioEmbedForm.tsx +++ b/src/components/SlateEditor/plugins/audio/AudioEmbedForm.tsx @@ -19,7 +19,6 @@ import { FieldRoot, SelectContent, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, } from "@ndla/primitives"; @@ -127,15 +126,13 @@ const EmbedForm = ({ onCancel, audio }: EmbedFormProps) => { - - - {collection.items.map((item) => ( - - {item.label} - - ))} - - + + {collection.items.map((item) => ( + + {item.label} + + ))} + {meta.error} diff --git a/src/components/SlateEditor/plugins/codeBlock/CodeBlockEditor.tsx b/src/components/SlateEditor/plugins/codeBlock/CodeBlockEditor.tsx index ffa2bf68e5..0eafe76edb 100644 --- a/src/components/SlateEditor/plugins/codeBlock/CodeBlockEditor.tsx +++ b/src/components/SlateEditor/plugins/codeBlock/CodeBlockEditor.tsx @@ -19,7 +19,6 @@ import { FieldRoot, SelectContent, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, } from "@ndla/primitives"; @@ -164,15 +163,13 @@ const CodeBlockEditor = ({ onSave, onAbort, highlight, content, setShowWarning } - - - {languageOptions.map((item) => ( - - {item.title} - - ))} - - + + {languageOptions.map((item) => ( + + {item.title} + + ))} + diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx index 77ee313756..1eae36776a 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarLanguageOptions.tsx @@ -12,7 +12,7 @@ import { Editor, Element, Transforms } from "slate"; import { ReactEditor, useSlate, useSlateSelection, useSlateSelector } from "slate-react"; import { createListCollection } from "@ark-ui/react"; import { Language } from "@ndla/icons/common"; -import { SelectContent, SelectRoot, SelectPositioner, SelectValueText, SelectLabel } from "@ndla/primitives"; +import { SelectContent, SelectRoot, SelectValueText, SelectLabel } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { ToolbarCategoryProps } from "./SlateToolbar"; import { LanguageType } from "./toolbarState"; @@ -98,19 +98,17 @@ export const ToolbarLanguageOptions = ({ options }: ToolbarCategoryProps - - - {collection.items.map((option) => ( - - {t(`languages.${option.value}`)} - - ))} - - + + {collection.items.map((option) => ( + + {t(`languages.${option.value}`)} + + ))} + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx index 2472c8b5e1..707ce5137e 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarTextOptions.tsx @@ -11,15 +11,7 @@ import { useTranslation } from "react-i18next"; import { Element, Editor, Transforms } from "slate"; import { ReactEditor, useSlate, useSlateSelection, useSlateSelector } from "slate-react"; import { createListCollection } from "@ark-ui/react"; -import { - SelectContent, - SelectItem, - SelectItemText, - SelectLabel, - SelectPositioner, - SelectRoot, - SelectValueText, -} from "@ndla/primitives"; +import { SelectContent, SelectItem, SelectItemText, SelectLabel, SelectRoot, SelectValueText } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { handleTextChange } from "./handleMenuClicks"; import { ToolbarCategoryProps } from "./SlateToolbar"; @@ -100,22 +92,20 @@ export const ToolbarTextOptions = ({ options }: ToolbarCategoryProps) {TriggerIcon && } - - - {collection.items.map((item) => { - const Icon = item.value ? iconMapping[item.value] : undefined; - return ( - - - {Icon && } - {t(`editorToolbar.${item.value}-value`)} - - - - ); - })} - - + + {collection.items.map((item) => { + const Icon = item.value ? iconMapping[item.value] : undefined; + return ( + + + {Icon && } + {t(`editorToolbar.${item.value}-value`)} + + + + ); + })} + ); }; diff --git a/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx b/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx index d535f84378..4567c71b6a 100644 --- a/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx +++ b/src/components/SlateEditor/plugins/toolbar/ToolbarToggle.tsx @@ -31,7 +31,7 @@ import { FormatList, Globe, } from "@ndla/icons/editor"; -import { Text, ToggleGroupItem, ToggleGroupRoot } from "@ndla/primitives"; +import { IconButton, Text, ToggleGroupItem, ToggleGroupRoot } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { FontWeightToken } from "@ndla/styled-system/tokens"; @@ -132,17 +132,18 @@ export const ToolbarToggleButton = forwardRef - {Icon && } - {children} + + {Icon && } + {children} + ); }, diff --git a/src/components/Taxonomy/OptGroupVersionSelector.tsx b/src/components/Taxonomy/OptGroupVersionSelector.tsx index 825f56211d..4748c5c1f6 100644 --- a/src/components/Taxonomy/OptGroupVersionSelector.tsx +++ b/src/components/Taxonomy/OptGroupVersionSelector.tsx @@ -9,14 +9,7 @@ import { TFunction } from "i18next"; import { ReactNode, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; -import { - SelectContent, - SelectItemGroup, - SelectItemGroupLabel, - SelectPositioner, - SelectRoot, - SelectValueText, -} from "@ndla/primitives"; +import { SelectContent, SelectItemGroup, SelectItemGroupLabel, SelectRoot, SelectValueText } from "@ndla/primitives"; import { Version, VersionType } from "@ndla/types-taxonomy"; import { GenericSelectItem, GenericSelectTrigger } from "../abstractions/Select"; @@ -99,21 +92,19 @@ export const OptGroupVersionSelector = ({ - - - {fakeDefault.name} - {optGroups.map((optGroup) => ( - - {optGroup.label} - {optGroup.options.map((option) => ( - - {option.name} - - ))} - - ))} - - + + {fakeDefault.name} + {optGroups.map((optGroup) => ( + + {optGroup.label} + {optGroup.options.map((option) => ( + + {option.name} + + ))} + + ))} + ); }; diff --git a/src/containers/App/components/FooterWrapper.tsx b/src/containers/App/components/FooterWrapper.tsx index 66d2f3de67..dd3577f818 100644 --- a/src/containers/App/components/FooterWrapper.tsx +++ b/src/containers/App/components/FooterWrapper.tsx @@ -11,7 +11,7 @@ import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; import emotionStyled from "@emotion/styled"; import { spacing } from "@ndla/core"; -import { SelectContent, SelectLabel, SelectPositioner, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; +import { SelectContent, SelectLabel, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; import { supportedLanguages } from "../../../i18n2"; @@ -79,15 +79,13 @@ const FooterWrapper = ({ showLocaleSelector }: Props) => { {t("languages.prefixChangeLanguage")} - - - {supportedLanguages.map((lang) => ( - - {t(`languages.${lang}`)} - - ))} - - + + {supportedLanguages.map((lang) => ( + + {t(`languages.${lang}`)} + + ))} + )} diff --git a/src/containers/ArticlePage/components/ResourceTypeSelect.tsx b/src/containers/ArticlePage/components/ResourceTypeSelect.tsx index cba506df9c..fcfc58a7d2 100644 --- a/src/containers/ArticlePage/components/ResourceTypeSelect.tsx +++ b/src/containers/ArticlePage/components/ResourceTypeSelect.tsx @@ -9,7 +9,7 @@ import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { SelectValueText, createListCollection } from "@ark-ui/react"; -import { SelectContent, SelectLabel, SelectPositioner, SelectRoot } from "@ndla/primitives"; +import { SelectContent, SelectLabel, SelectRoot } from "@ndla/primitives"; import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; import { selectedResourceTypeValue } from "../../../util/taxonomyHelpers"; @@ -70,15 +70,13 @@ const ResourceTypeSelect = ({ availableResourceTypes, selectedResourceTypes, onC - - - {options.map((item) => ( - - {item.label} - - ))} - - + + {options.map((item) => ( + + {item.label} + + ))} + ); }; diff --git a/src/containers/FormikForm/GrepCodesField.tsx b/src/containers/FormikForm/GrepCodesField.tsx index 58b7cb80fb..e93ab12f2a 100644 --- a/src/containers/FormikForm/GrepCodesField.tsx +++ b/src/containers/FormikForm/GrepCodesField.tsx @@ -15,7 +15,6 @@ import { ComboboxContent, ComboboxItem, ComboboxList, - ComboboxPositioner, ComboboxRoot, FieldHelper, FieldLabel, @@ -155,20 +154,18 @@ const GrepCodesField = () => { }} triggerable /> - - - - {collection.items.map((item) => ( - - - - ))} - - {searchQuery.isSuccess && ( - {t("dropdown.numberHits", { hits: searchQuery.data?.totalCount ?? 0 })} - )} - - + + + {collection.items.map((item) => ( + + + + ))} + + {searchQuery.isSuccess && ( + {t("dropdown.numberHits", { hits: searchQuery.data?.totalCount ?? 0 })} + )} + {Object.entries(grepCodes).map(([code, title]) => ( diff --git a/src/containers/FormikForm/components/ContributorsField.tsx b/src/containers/FormikForm/components/ContributorsField.tsx index 509b1c52ce..314b036f35 100644 --- a/src/containers/FormikForm/components/ContributorsField.tsx +++ b/src/containers/FormikForm/components/ContributorsField.tsx @@ -22,7 +22,6 @@ import { SelectContent, SelectHiddenSelect, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, } from "@ndla/primitives"; @@ -133,15 +132,13 @@ const Contributor = ({ type, onAddNew, onRemove }: ContributorProps) => { - - - {collection.items.map((item) => ( - - {item.translation} - - ))} - - + + {collection.items.map((item) => ( + + {item.translation} + + ))} + diff --git a/src/containers/FormikForm/components/LicenseField.tsx b/src/containers/FormikForm/components/LicenseField.tsx index 0e0f1cd931..b01cece815 100644 --- a/src/containers/FormikForm/components/LicenseField.tsx +++ b/src/containers/FormikForm/components/LicenseField.tsx @@ -15,7 +15,6 @@ import { SelectContent, SelectHiddenSelect, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, } from "@ndla/primitives"; @@ -65,15 +64,13 @@ const LicenseField = ({ name = "license", enableLicenseNA }: Props) => { - - - {collection.items.map((item) => ( - - {item.title} - - ))} - - + + {collection.items.map((item) => ( + + {item.title} + + ))} + diff --git a/src/containers/FormikForm/components/PrioritySelect.tsx b/src/containers/FormikForm/components/PrioritySelect.tsx index 8c5779d4d3..6ea475506e 100644 --- a/src/containers/FormikForm/components/PrioritySelect.tsx +++ b/src/containers/FormikForm/components/PrioritySelect.tsx @@ -9,7 +9,7 @@ import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; -import { SelectContent, SelectLabel, SelectPositioner, SelectRoot, SelectValueText } from "@ndla/primitives"; +import { SelectContent, SelectLabel, SelectRoot, SelectValueText } from "@ndla/primitives"; import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; const priorityMapping = { @@ -45,15 +45,13 @@ const PrioritySelect = ({ priority, updatePriority }: Props) => { - - - {collection.items.map((item) => ( - - {item.label} - - ))} - - + + {collection.items.map((item) => ( + + {item.label} + + ))} + ); }; diff --git a/src/containers/FormikForm/components/ResponsibleSelect.tsx b/src/containers/FormikForm/components/ResponsibleSelect.tsx index dda2bdf96b..806e107226 100644 --- a/src/containers/FormikForm/components/ResponsibleSelect.tsx +++ b/src/containers/FormikForm/components/ResponsibleSelect.tsx @@ -9,7 +9,7 @@ import sortBy from "lodash/sortBy"; import { useState, useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; -import { SelectContent, SelectLabel, SelectPositioner, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; +import { SelectContent, SelectLabel, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; import { DRAFT_RESPONSIBLE } from "../../../constants"; @@ -88,19 +88,17 @@ const ResponsibleSelect = ({ responsible, setResponsible, onSave, responsibleId - - - {!collection.items.length ? ( - {t("form.responsible.noResults")} - ) : ( - collection.items.map((item) => ( - - {item.name} - - )) - )} - - + + {!collection.items.length ? ( + {t("form.responsible.noResults")} + ) : ( + collection.items.map((item) => ( + + {item.name} + + )) + )} + ); }; diff --git a/src/containers/FormikForm/components/StatusSelect.tsx b/src/containers/FormikForm/components/StatusSelect.tsx index 41b3c214cb..8dea0fdeea 100644 --- a/src/containers/FormikForm/components/StatusSelect.tsx +++ b/src/containers/FormikForm/components/StatusSelect.tsx @@ -8,7 +8,7 @@ import { useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { createListCollection } from "@ark-ui/react"; -import { SelectContent, SelectLabel, SelectPositioner, SelectRoot, SelectValueText } from "@ndla/primitives"; +import { SelectContent, SelectLabel, SelectRoot, SelectValueText } from "@ndla/primitives"; import { styled } from "@ndla/styled-system/jsx"; import { IStatus as DraftStatus } from "@ndla/types-backend/draft-api"; import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; @@ -70,15 +70,13 @@ const StatusSelect = ({ status, setStatus, onSave, statusStateMachine, entitySta placeholder={entityStatus?.current === PUBLISHED ? t("form.status.published") : t("searchForm.types.status")} /> - - - {collection.items.map((item) => ( - - {item.label} - - ))} - - + + {collection.items.map((item) => ( + + {item.label} + + ))} + ); }; diff --git a/src/containers/GlossPage/components/ExampleField.tsx b/src/containers/GlossPage/components/ExampleField.tsx index 566ec14783..11752e86ae 100644 --- a/src/containers/GlossPage/components/ExampleField.tsx +++ b/src/containers/GlossPage/components/ExampleField.tsx @@ -22,7 +22,6 @@ import { SelectContent, SelectHiddenSelect, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, } from "@ndla/primitives"; @@ -132,15 +131,13 @@ const ExampleField = ({ example, name, index, exampleIndex, onRemoveExample }: P placeholder={t("form.gloss.choose", { label: t("form.gloss.language").toLowerCase() })} /> - - - {collection.items.map((language) => ( - - {t(`languages.${language}`)} - - ))} - - + + {collection.items.map((language) => ( + + {t(`languages.${language}`)} + + ))} + diff --git a/src/containers/GlossPage/components/GlossDataSection.tsx b/src/containers/GlossPage/components/GlossDataSection.tsx index 72b7c17efc..0b145d1727 100644 --- a/src/containers/GlossPage/components/GlossDataSection.tsx +++ b/src/containers/GlossPage/components/GlossDataSection.tsx @@ -19,7 +19,6 @@ import { SelectContent, SelectHiddenSelect, SelectLabel, - SelectPositioner, SelectRoot, SelectValueText, Text, @@ -93,15 +92,13 @@ const GlossDataSection = ({ glossLanguage }: Props) => { - - - {languageCollection.items.map((language) => ( - - {t(`languages.${language}`)} - - ))} - - + + {languageCollection.items.map((language) => ( + + {t(`languages.${language}`)} + + ))} + {meta.error} @@ -121,16 +118,14 @@ const GlossDataSection = ({ glossLanguage }: Props) => { - - - {wordClassCollection.items.map((wordClass) => ( - - {t(`wordClass.${wordClass}`)} - - ))} - - - + + {wordClassCollection.items.map((wordClass) => ( + + {t(`wordClass.${wordClass}`)} + + ))} + + )} diff --git a/src/containers/Masthead/components/MastheadSearch.tsx b/src/containers/Masthead/components/MastheadSearch.tsx index d1e226b204..d5974fe622 100644 --- a/src/containers/Masthead/components/MastheadSearch.tsx +++ b/src/containers/Masthead/components/MastheadSearch.tsx @@ -19,7 +19,6 @@ import { ComboboxItem, ComboboxItemText, ComboboxLabel, - ComboboxPositioner, ComboboxRoot, IconButton, Input, @@ -245,22 +244,20 @@ export const MastheadSearch = () => {
- - - {collection.items.length ? ( - collection.items.map((item) => ( - - - {item.searchPhrase} - - - - )) - ) : ( - {t("welcomePage.noHitsSavedSearch")} - )} - - + + {collection.items.length ? ( + collection.items.map((item) => ( + + + {item.searchPhrase} + + + + )) + ) : ( + {t("welcomePage.noHitsSavedSearch")} + )} + ); diff --git a/src/containers/Messages/__tests__/__snapshots__/Messages-test.tsx.snap b/src/containers/Messages/__tests__/__snapshots__/Messages-test.tsx.snap index 1c1f8a31d9..45d4899b21 100644 --- a/src/containers/Messages/__tests__/__snapshots__/Messages-test.tsx.snap +++ b/src/containers/Messages/__tests__/__snapshots__/Messages-test.tsx.snap @@ -543,7 +543,7 @@ exports[`Messages > auth0 messages provides a cancel button 1`] = ` Avbryt - - - {collection.items.map((item) => ( - - {item.label} - - - - - ))} - - + + {collection.items.map((item) => ( + + {item.label} + + + + + ))} + ); diff --git a/src/containers/WelcomePage/components/worklist/SubjectCombobox.tsx b/src/containers/WelcomePage/components/worklist/SubjectCombobox.tsx index 169783abd6..992df07135 100644 --- a/src/containers/WelcomePage/components/worklist/SubjectCombobox.tsx +++ b/src/containers/WelcomePage/components/worklist/SubjectCombobox.tsx @@ -23,7 +23,6 @@ import { ComboboxItemIndicator, ComboboxItemText, ComboboxLabel, - ComboboxPositioner, ComboboxRoot, ComboboxTrigger, IconButton, @@ -158,27 +157,25 @@ const SubjectCombobox = ({ - - - {/*TODO: Evaluate if this needs to be made accessible (?) */} - {isLoading ? ( - - - - ) : !collection.items.length ? ( - {t("form.responsible.noResults")} - ) : ( - collection.items.map((item) => ( - - {item.label} - - - - - )) - )} - - + + {/*TODO: Evaluate if this needs to be made accessible (?) */} + {isLoading ? ( + + + + ) : !collection.items.length ? ( + {t("form.responsible.noResults")} + ) : ( + collection.items.map((item) => ( + + {item.label} + + + + + )) + )} + ); }; diff --git a/yarn.lock b/yarn.lock index 815e3eed43..4c2db39cc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1891,12 +1891,12 @@ __metadata: languageName: node linkType: hard -"@ndla/article-converter@npm:^10.0.73-alpha.0": - version: 10.0.73-alpha.0 - resolution: "@ndla/article-converter@npm:10.0.73-alpha.0" +"@ndla/article-converter@npm:^10.0.74-alpha.0": + version: 10.0.74-alpha.0 + resolution: "@ndla/article-converter@npm:10.0.74-alpha.0" dependencies: - "@ndla/primitives": "npm:^1.0.54-alpha.0" - "@ndla/ui": "npm:^56.0.70-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" + "@ndla/ui": "npm:^56.0.71-alpha.0" html-react-parser: "npm:^5.1.8" peerDependencies: i18next: ">= 23.11.5" @@ -1904,39 +1904,22 @@ __metadata: react-dom: ">= 16.8.0" react-i18next: ^14.1.1 react-router-dom: ">= 6.0.0" - checksum: 10c0/5426157b3c1122438747157fee83d0f3358eea1629d775240b68ad4fcf373d301313a0c71bb7a03a928d2747fe5909fc3e052a72cd06cc2254284c8950b1c68f + checksum: 10c0/d10f7c983eb21fc2e0960451baa6471b7fda0083fe76cecb2158317eff80f363d9ff41620f0637e7be862a9c83d93b4dbda144c2ace8e02d07127e16ff55c774 languageName: node linkType: hard -"@ndla/audio-search@npm:^7.0.60-alpha.0": - version: 7.0.60-alpha.0 - resolution: "@ndla/audio-search@npm:7.0.60-alpha.0" +"@ndla/audio-search@npm:^7.0.61-alpha.0": + version: 7.0.61-alpha.0 + resolution: "@ndla/audio-search@npm:7.0.61-alpha.0" dependencies: "@ndla/icons": "npm:^8.0.43-alpha.0" "@ndla/licenses": "npm:^8.0.3-alpha.0" - "@ndla/primitives": "npm:^1.0.54-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" "@ndla/styled-system": "npm:^0.0.27" peerDependencies: react: ">= 18" react-dom: ">= 18" - checksum: 10c0/37c392f845f27bfadc9a595f5634b8e5a3a42ca2576da393550a22e4fddc54ce26f8097c52f0ab4ed1bb272f56402285fd10161fd34fca70e107ba251bc5b211 - languageName: node - linkType: hard - -"@ndla/button@npm:^15.0.44-alpha.0": - version: 15.0.44-alpha.0 - resolution: "@ndla/button@npm:15.0.44-alpha.0" - dependencies: - "@ndla/core": "npm:^5.0.2" - "@ndla/dropdown-menu": "npm:^1.0.40-alpha.0" - "@ndla/icons": "npm:^8.0.43-alpha.0" - peerDependencies: - "@emotion/react": ^11.10.4 - "@emotion/styled": ^11.10.4 - react: ">= 16.8.0" - react-dom: ">= 16.8.0" - react-i18next: ^14.1.1 - checksum: 10c0/9bcdc9fc9da16d8da64ac218d4cc3a89b7c557ebcf2c3f61c56b9ae5d4ceeada279444db2d009176cac3ab5fef0484b7742acc083e15af0edc49335a1c23c7f3 + checksum: 10c0/4fa28e55c5f9a10bfa71f936c4c26f466638f3d5f24e1d21583fe0643b081865522698957de585aa415bc69bd138b10439a210c29ca86df966d06348a89f4dac languageName: node linkType: hard @@ -1950,21 +1933,6 @@ __metadata: languageName: node linkType: hard -"@ndla/dropdown-menu@npm:^1.0.40-alpha.0": - version: 1.0.40-alpha.0 - resolution: "@ndla/dropdown-menu@npm:1.0.40-alpha.0" - dependencies: - "@ndla/core": "npm:^5.0.2" - "@radix-ui/react-dropdown-menu": "npm:^2.0.6" - "@radix-ui/react-slot": "npm:^1.0.2" - peerDependencies: - "@emotion/styled": ^11.10.4 - react: ">= 16.8.0" - react-dom: ">= 16.8.0" - checksum: 10c0/259f73ec708153de15f92f26b7d0a3f583e221bc1f6d67c754d78cc72d1db54f0f753fdcb266c2915a4d03611d7f1860753c3990e544bb68d4445097affcae19 - languageName: node - linkType: hard - "@ndla/error-reporter@npm:^2.0.4": version: 2.0.4 resolution: "@ndla/error-reporter@npm:2.0.4" @@ -1998,19 +1966,19 @@ __metadata: languageName: node linkType: hard -"@ndla/image-search@npm:^11.0.62-alpha.0": - version: 11.0.62-alpha.0 - resolution: "@ndla/image-search@npm:11.0.62-alpha.0" +"@ndla/image-search@npm:^11.0.63-alpha.0": + version: 11.0.63-alpha.0 + resolution: "@ndla/image-search@npm:11.0.63-alpha.0" dependencies: "@ndla/icons": "npm:^8.0.43-alpha.0" "@ndla/licenses": "npm:^8.0.3-alpha.0" - "@ndla/primitives": "npm:^1.0.54-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" "@ndla/styled-system": "npm:^0.0.27" pretty-bytes: "npm:^5.6.0" peerDependencies: react: ">= 18" react-dom: ">= 18" - checksum: 10c0/3a12b82634a9c37d4364abf54988f33b49fbc6b42aa275657bf4e7efaff22de7146e737d54a2e948f095235053f972ee4f15d5b9c490b43f9c9f44929fca94ad + checksum: 10c0/05f29ed7f3088879fac1465089460171a6e4843c1aa5c9b0a338eadb8e0180c35da131721af5ef4fc46000c5ee4d11bf3e388e7445b15ed6c9d591a0cced1e72 languageName: node linkType: hard @@ -2028,9 +1996,9 @@ __metadata: languageName: node linkType: hard -"@ndla/primitives@npm:^1.0.54-alpha.0": - version: 1.0.54-alpha.0 - resolution: "@ndla/primitives@npm:1.0.54-alpha.0" +"@ndla/primitives@npm:^1.0.55-alpha.0": + version: 1.0.55-alpha.0 + resolution: "@ndla/primitives@npm:1.0.55-alpha.0" dependencies: "@ark-ui/react": "npm:^4.1.2" "@ndla/styled-system": "npm:^0.0.27" @@ -2038,21 +2006,21 @@ __metadata: peerDependencies: react: ">= 18" react-dom: ">= 18" - checksum: 10c0/47a3f0798c0341c1ebe8da4c30dc8fc64a894fb99633a8e3f4cfd87dbc974b16d4e7c6a0c9b3d218ae82eb89a901c22af39da68183c01c29ee93cd5c25c035e6 + checksum: 10c0/6294e7432f3a26ad71bb35a33f9b9b6af1b7a6a60880a5014b12761db71d3688cbe254a093c4baf509f9d61257a32a9bf0673f4ec90d4ac93e91c56f874fefb2 languageName: node linkType: hard -"@ndla/safelink@npm:^7.0.55-alpha.0": - version: 7.0.55-alpha.0 - resolution: "@ndla/safelink@npm:7.0.55-alpha.0" +"@ndla/safelink@npm:^7.0.56-alpha.0": + version: 7.0.56-alpha.0 + resolution: "@ndla/safelink@npm:7.0.56-alpha.0" dependencies: - "@ndla/primitives": "npm:^1.0.54-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" "@ndla/styled-system": "npm:^0.0.27" peerDependencies: react: ">= 18" react-dom: ">= 18" react-router-dom: ^6.3.0 - checksum: 10c0/2a5a0c6507ff3650a476b208ade968539117557eeb1c38a6fa7b068bae0ca296a4e45eccebcb8c83c11d7a95e6afe22d561940498d661fa0903845a3f2a9c42a + checksum: 10c0/41d9aeda1d470a59e9e35381719467dcfc8bac88211200997b5fb89e0a569569e25704da8eba366199a33f3c9419916c05edfadbcdf34482f6d40eed40435aed languageName: node linkType: hard @@ -2116,15 +2084,15 @@ __metadata: languageName: node linkType: hard -"@ndla/ui@npm:^56.0.70-alpha.0": - version: 56.0.70-alpha.0 - resolution: "@ndla/ui@npm:56.0.70-alpha.0" +"@ndla/ui@npm:^56.0.71-alpha.0": + version: 56.0.71-alpha.0 + resolution: "@ndla/ui@npm:56.0.71-alpha.0" dependencies: "@ndla/core": "npm:^5.0.2" "@ndla/icons": "npm:^8.0.43-alpha.0" "@ndla/licenses": "npm:^8.0.3-alpha.0" - "@ndla/primitives": "npm:^1.0.54-alpha.0" - "@ndla/safelink": "npm:^7.0.55-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" + "@ndla/safelink": "npm:^7.0.56-alpha.0" "@ndla/styled-system": "npm:^0.0.27" "@ndla/util": "npm:^5.0.0-alpha.0" html-react-parser: "npm:^5.1.8" @@ -2135,7 +2103,7 @@ __metadata: react-dom: ">= 18" react-i18next: ^14.1.1 react-router-dom: "> 6.0.0" - checksum: 10c0/447395d93a948c25306e5fadac68a106cdb7d7596c85fa700a9aeacf9a064938401c4351ba0e07ecc79e574a193cf0cb0fd3afcfd48054d75850eefd869967d2 + checksum: 10c0/cdb88c64fb7fc495225eed1f06d18bb6e0d79c4ef8d3fa604b73b39e5ab4465870bcc71041a2b7475e66fef90571ee89a97f2770da91b2c95b5b82809b7019c2 languageName: node linkType: hard @@ -2148,18 +2116,18 @@ __metadata: languageName: node linkType: hard -"@ndla/video-search@npm:^8.0.59-alpha.0": - version: 8.0.59-alpha.0 - resolution: "@ndla/video-search@npm:8.0.59-alpha.0" +"@ndla/video-search@npm:^8.0.60-alpha.0": + version: 8.0.60-alpha.0 + resolution: "@ndla/video-search@npm:8.0.60-alpha.0" dependencies: "@ndla/icons": "npm:^8.0.43-alpha.0" "@ndla/licenses": "npm:^8.0.3-alpha.0" - "@ndla/primitives": "npm:^1.0.54-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" "@ndla/styled-system": "npm:^0.0.27" peerDependencies: react: ">= 18" react-dom: ">= 18" - checksum: 10c0/d45a1e26264d4b0e1f2ef7c42a010768605ff641fded3f5217c95dfdd31911a09537d97e618b7964b6cf8a353ddf68d2e2b7d2ab85eacd419c0d42bc4ed4b961 + checksum: 10c0/f46b6c71be30e61a4d95ad678d3b1987a52645a212eb2f18d6889959b9a8bb0291b5368540e07ce958dd490b58884c4d4ee614ea604faa962c16cf5cb2247b06 languageName: node linkType: hard @@ -2478,6 +2446,13 @@ __metadata: languageName: node linkType: hard +"@radix-ui/primitive@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/primitive@npm:1.1.0" + checksum: 10c0/1dcc8b5401799416ff8bdb15c7189b4536c193220ad8fd348a48b88f804ee38cec7bd03e2b9641f7da24610e2f61f23a306911ce883af92c4e8c1abac634cb61 + languageName: node + linkType: hard + "@radix-ui/react-arrow@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-arrow@npm:1.0.3" @@ -2498,6 +2473,25 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-arrow@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-arrow@npm:1.1.0" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/cbe059dfa5a9c1677478d363bb5fd75b0c7a08221d0ac7f8e7b9aec9dbae9754f6a3518218cf63e4ed53df6c36d193c8d2618d03433a37aa0cb7ee77a60a591f + languageName: node + linkType: hard + "@radix-ui/react-collection@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-collection@npm:1.0.3" @@ -2521,6 +2515,28 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-collection@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-collection@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-slot": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/fecb9f0871c827070a8794b39c7379fdc7d0855c4b05804f0b395eef39c37b2c2b6779865d6cb35d3bc74b6b380107bd8b3754d1730a34ea88913e6cd0eb84d4 + languageName: node + linkType: hard + "@radix-ui/react-compose-refs@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-compose-refs@npm:1.0.1" @@ -2536,6 +2552,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-compose-refs@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-compose-refs@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7e18706084397d9458ca3473d8565b10691da06f6499a78edbcc4bd72cde08f62e91120658d17d58c19fc39d6b1dffe0133cc4535c8f5fce470abd478f6107e5 + languageName: node + linkType: hard + "@radix-ui/react-context@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-context@npm:1.0.1" @@ -2551,6 +2580,32 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-context@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-context@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/c843980f568cc61b512708863ec84c42a02e0f88359b22ad1c0e290cea3e6d7618eccbd2cd37bd974fadaa7636cbed5bda27553722e61197eb53852eaa34f1bb + languageName: node + linkType: hard + +"@radix-ui/react-context@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-context@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/fc4ace9d79d7954c715ade765e06c95d7e1b12a63a536bcbe842fb904f03f88fc5bd6e38d44bd23243d37a270b4c44380fedddaeeae2d274f0b898a20665aba2 + languageName: node + linkType: hard + "@radix-ui/react-direction@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-direction@npm:1.0.1" @@ -2566,6 +2621,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-direction@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-direction@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/eb07d8cc3ae2388b824e0a11ae0e3b71fb0c49972b506e249cec9f27a5b7ef4305ee668c98b674833c92e842163549a83beb0a197dec1ec65774bdeeb61f932c + languageName: node + linkType: hard + "@radix-ui/react-dismissable-layer@npm:1.0.5": version: 1.0.5 resolution: "@radix-ui/react-dismissable-layer@npm:1.0.5" @@ -2590,29 +2658,51 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-dropdown-menu@npm:^2.0.6": - version: 2.0.6 - resolution: "@radix-ui/react-dropdown-menu@npm:2.0.6" +"@radix-ui/react-dismissable-layer@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.1" dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-id": "npm:1.0.1" - "@radix-ui/react-menu": "npm:2.0.6" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-controllable-state": "npm:1.0.1" + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-escape-keydown": "npm:1.1.0" peerDependencies: "@types/react": "*" "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: "@types/react": optional: true "@types/react-dom": optional: true - checksum: 10c0/525cab53547d2ce2904518b1f66b62179d656c57c8d6dd7dbe863cc05025d8bad535f44011e2735b07fc500579c3d64d89a9a39593d4c8f91f31052d75b729e1 + checksum: 10c0/637f8d55437bd2269d5aa9fa48e869eade31082cd950b5efcc5f0d9ed016b46feb7fcfcc115ba9972dba68c4686b57873d84aca67ece76ab77463e7de995f6da + languageName: node + linkType: hard + +"@radix-ui/react-dropdown-menu@npm:^2.1.2": + version: 2.1.2 + resolution: "@radix-ui/react-dropdown-menu@npm:2.1.2" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-menu": "npm:2.1.2" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/28e84cb116a34c3a73cd9be774170fc920fad6254c1ce285e8e3d86e33c02011229adc5590e385a42106b41bced23e0a482e884e6894e37f68d7e87c76171279 languageName: node linkType: hard @@ -2631,6 +2721,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-focus-guards@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-focus-guards@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/2e99750ca593083a530542a185d656b45b100752353a7a193a67566e3c256414a76fa9171d152f8c0167b8d6c1fdf62b2e07750d7af2974bf8ef39eb204aa537 + languageName: node + linkType: hard + "@radix-ui/react-focus-scope@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-focus-scope@npm:1.0.4" @@ -2653,6 +2756,27 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-focus-scope@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-focus-scope@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/2593d4bbd4a3525624675ec1d5a591a44f015f43f449b99a5a33228159b83f445e8f1c6bc6f9f2011387abaeadd3df406623c08d4e795b7ae509795652a1d069 + languageName: node + linkType: hard + "@radix-ui/react-id@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-id@npm:1.0.1" @@ -2669,40 +2793,54 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-menu@npm:2.0.6": - version: 2.0.6 - resolution: "@radix-ui/react-menu@npm:2.0.6" +"@radix-ui/react-id@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-id@npm:1.1.0" dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-collection": "npm:1.0.3" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-direction": "npm:1.0.1" - "@radix-ui/react-dismissable-layer": "npm:1.0.5" - "@radix-ui/react-focus-guards": "npm:1.0.1" - "@radix-ui/react-focus-scope": "npm:1.0.4" - "@radix-ui/react-id": "npm:1.0.1" - "@radix-ui/react-popper": "npm:1.1.3" - "@radix-ui/react-portal": "npm:1.0.4" - "@radix-ui/react-presence": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-roving-focus": "npm:1.0.4" - "@radix-ui/react-slot": "npm:1.0.2" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/acf13e29e51ee96336837fc0cfecc306328b20b0e0070f6f0f7aa7a621ded4a1ee5537cfad58456f64bae76caa7f8769231e88dc7dc106197347ee433c275a79 + languageName: node + linkType: hard + +"@radix-ui/react-menu@npm:2.1.2": + version: 2.1.2 + resolution: "@radix-ui/react-menu@npm:2.1.2" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-collection": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.1" + "@radix-ui/react-direction": "npm:1.1.0" + "@radix-ui/react-dismissable-layer": "npm:1.1.1" + "@radix-ui/react-focus-guards": "npm:1.1.1" + "@radix-ui/react-focus-scope": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-popper": "npm:1.2.0" + "@radix-ui/react-portal": "npm:1.1.2" + "@radix-ui/react-presence": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-roving-focus": "npm:1.1.0" + "@radix-ui/react-slot": "npm:1.1.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" aria-hidden: "npm:^1.1.1" - react-remove-scroll: "npm:2.5.5" + react-remove-scroll: "npm:2.6.0" peerDependencies: "@types/react": "*" "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: "@types/react": optional: true "@types/react-dom": optional: true - checksum: 10c0/06926fa59cb8f5614f2e1a085ea1cbf09631ae28fb6e5d6e6d2a0a84d24979e3aca311cdb19dfdb254c1823ff85fd5250c29d4463f8f7622dd523e35df3fce1d + checksum: 10c0/4259f6fbc63048d58bffab443abda9b56ea6b0a28f1e4ae91787a360b9a31e7604de06c8fc70be861c1aaa7abff2858c9314aa3fffbc375c27b0c9aa219a51af languageName: node linkType: hard @@ -2769,7 +2907,35 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-portal@npm:1.0.4, @radix-ui/react-portal@npm:^1.0.3": +"@radix-ui/react-popper@npm:1.2.0": + version: 1.2.0 + resolution: "@radix-ui/react-popper@npm:1.2.0" + dependencies: + "@floating-ui/react-dom": "npm:^2.0.0" + "@radix-ui/react-arrow": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + "@radix-ui/react-use-rect": "npm:1.1.0" + "@radix-ui/react-use-size": "npm:1.1.0" + "@radix-ui/rect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/a78ea534b9822d07153fff0895b6cdf742e7213782b140b3ab94a76df0ca70e6001925aea946e99ca680fc63a7fcca49c1d62e8dc5a2f651692fba3541e180c0 + languageName: node + linkType: hard + +"@radix-ui/react-portal@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-portal@npm:1.0.4" dependencies: @@ -2789,6 +2955,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-portal@npm:1.1.2, @radix-ui/react-portal@npm:^1.0.3": + version: 1.1.2 + resolution: "@radix-ui/react-portal@npm:1.1.2" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/836967330893b16b85371775ed1a59e038ce99189f4851cfa976bde2710d704c2a9e49e0a5206e7ac3fcf8a67ddd2d126b8352a88f295d6ef49d04e269736ed1 + languageName: node + linkType: hard + "@radix-ui/react-presence@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-presence@npm:1.0.1" @@ -2810,6 +2996,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-presence@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-presence@npm:1.1.1" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/777cda0406450ff5ca0e49235e486237723323d046a3382e35a0e78eededccfc95a76a9b5fecd7404dac793264762f4bc10111af1e08f8cc2d4d571d7971220e + languageName: node + linkType: hard + "@radix-ui/react-primitive@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-primitive@npm:1.0.3" @@ -2830,6 +3036,25 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-primitive@npm:2.0.0": + version: 2.0.0 + resolution: "@radix-ui/react-primitive@npm:2.0.0" + dependencies: + "@radix-ui/react-slot": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/00cb6ca499252ca848c299212ba6976171cea7608b10b3f9a9639d6732dea2df1197ba0d97c001a4fdb29313c3e7fc2a490f6245dd3579617a0ffd85ae964fdd + languageName: node + linkType: hard + "@radix-ui/react-roving-focus@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-roving-focus@npm:1.0.4" @@ -2858,6 +3083,33 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-roving-focus@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-roving-focus@npm:1.1.0" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-collection": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-direction": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/ce367d3033a12d639a8d445d2efa090aa4bc5a78125be568f8c8e4e59f30afd51b585a90031ec18cdba19afbaf1974633dbc0c2c3d2a14d9eb1bfea2ddbe5369 + languageName: node + linkType: hard + "@radix-ui/react-separator@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-separator@npm:1.0.3" @@ -2878,7 +3130,7 @@ __metadata: languageName: node linkType: hard -"@radix-ui/react-slot@npm:1.0.2, @radix-ui/react-slot@npm:^1.0.2": +"@radix-ui/react-slot@npm:1.0.2": version: 1.0.2 resolution: "@radix-ui/react-slot@npm:1.0.2" dependencies: @@ -2894,6 +3146,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slot@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-slot@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/a2e8bfb70c440506dd84a1a274f9a8bc433cca37ceae275e53552c9122612e3837744d7fc6f113d6ef1a11491aa914f4add71d76de41cb6d4db72547a8e261ae + languageName: node + linkType: hard + "@radix-ui/react-toggle-group@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-toggle-group@npm:1.0.4" @@ -2983,6 +3250,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-callback-ref@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/e954863f3baa151faf89ac052a5468b42650efca924417470efd1bd254b411a94c69c30de2fdbb90187b38cb984795978e12e30423dc41e4309d93d53b66d819 + languageName: node + linkType: hard + "@radix-ui/react-use-controllable-state@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-controllable-state@npm:1.0.1" @@ -2999,6 +3279,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-controllable-state@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/2af883b5b25822ac226e60a6bfde647c0123a76345052a90219026059b3f7225844b2c13a9a16fba859c1cda5fb3d057f2a04503f71780e607516492db4eb3a1 + languageName: node + linkType: hard + "@radix-ui/react-use-escape-keydown@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-use-escape-keydown@npm:1.0.3" @@ -3015,6 +3310,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-escape-keydown@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/910fd696e5a0994b0e06b9cb68def8a865f47951a013ec240c77db2a9e1e726105602700ef5e5f01af49f2f18fe0e73164f9a9651021f28538ef8a30d91f3fbb + languageName: node + linkType: hard + "@radix-ui/react-use-layout-effect@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-layout-effect@npm:1.0.1" @@ -3030,6 +3340,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-layout-effect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/9bf87ece1845c038ed95863cfccf9d75f557c2400d606343bab0ab3192b9806b9840e6aa0a0333fdf3e83cf9982632852192f3e68d7d8367bc8c788dfdf8e62b + languageName: node + linkType: hard + "@radix-ui/react-use-rect@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-rect@npm:1.0.1" @@ -3046,6 +3369,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-rect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-rect@npm:1.1.0" + dependencies: + "@radix-ui/rect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/c2e30150ab49e2cec238cda306fd748c3d47fb96dcff69a3b08e1d19108d80bac239d48f1747a25dadca614e3e967267d43b91e60ea59db2befbc7bea913ff84 + languageName: node + linkType: hard + "@radix-ui/react-use-size@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-size@npm:1.0.1" @@ -3062,6 +3400,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-size@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-size@npm:1.1.0" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/4c8b89037597fdc1824d009e0c941b510c7c6c30f83024cc02c934edd748886786e7d9f36f57323b02ad29833e7fa7e8974d81969b4ab33d8f41661afa4f30a6 + languageName: node + linkType: hard + "@radix-ui/rect@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/rect@npm:1.0.1" @@ -3071,6 +3424,13 @@ __metadata: languageName: node linkType: hard +"@radix-ui/rect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/rect@npm:1.1.0" + checksum: 10c0/a26ff7f8708fb5f2f7949baad70a6b2a597d761ee4dd4aadaf1c1a33ea82ea23dfef6ce6366a08310c5d008cdd60b2e626e4ee03fa342bd5f246ddd9d427f6be + languageName: node + linkType: hard + "@rollup/pluginutils@npm:^4.0.0": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" @@ -6689,28 +7049,28 @@ __metadata: "@fontsource/source-code-pro": "npm:^4.5.9" "@fontsource/source-sans-pro": "npm:^4.5.9" "@fontsource/source-serif-pro": "npm:^4.5.7" - "@ndla/article-converter": "npm:^10.0.73-alpha.0" - "@ndla/audio-search": "npm:^7.0.60-alpha.0" - "@ndla/button": "npm:^15.0.44-alpha.0" + "@ndla/article-converter": "npm:^10.0.74-alpha.0" + "@ndla/audio-search": "npm:^7.0.61-alpha.0" "@ndla/error-reporter": "npm:^2.0.4" "@ndla/hooks": "npm:^2.1.9" "@ndla/icons": "npm:^8.0.43-alpha.0" - "@ndla/image-search": "npm:^11.0.62-alpha.0" + "@ndla/image-search": "npm:^11.0.63-alpha.0" "@ndla/licenses": "npm:^8.0.3-alpha.0" "@ndla/preset-panda": "npm:^0.0.44" - "@ndla/primitives": "npm:^1.0.54-alpha.0" - "@ndla/safelink": "npm:^7.0.55-alpha.0" + "@ndla/primitives": "npm:^1.0.55-alpha.0" + "@ndla/safelink": "npm:^7.0.56-alpha.0" "@ndla/scripts": "npm:^2.1.2" "@ndla/styled-system": "npm:^0.0.27" "@ndla/tracker": "npm:^5.0.11-alpha.0" "@ndla/types-backend": "npm:^0.2.96" "@ndla/types-embed": "npm:^5.0.4-alpha.0" "@ndla/types-taxonomy": "npm:^1.0.30" - "@ndla/ui": "npm:^56.0.70-alpha.0" + "@ndla/ui": "npm:^56.0.71-alpha.0" "@ndla/util": "npm:^5.0.0-alpha.0" - "@ndla/video-search": "npm:^8.0.59-alpha.0" + "@ndla/video-search": "npm:^8.0.60-alpha.0" "@pandacss/dev": "npm:^0.46.1" "@playwright/test": "npm:^1.42.0" + "@radix-ui/react-dropdown-menu": "npm:^2.1.2" "@radix-ui/react-popover": "npm:^1.0.3" "@radix-ui/react-portal": "npm:^1.0.3" "@radix-ui/react-toolbar": "npm:^1.0.4" @@ -11869,9 +12229,9 @@ __metadata: languageName: node linkType: hard -"react-remove-scroll-bar@npm:^2.3.3": - version: 2.3.4 - resolution: "react-remove-scroll-bar@npm:2.3.4" +"react-remove-scroll-bar@npm:^2.3.3, react-remove-scroll-bar@npm:^2.3.6": + version: 2.3.6 + resolution: "react-remove-scroll-bar@npm:2.3.6" dependencies: react-style-singleton: "npm:^2.2.1" tslib: "npm:^2.0.0" @@ -11881,7 +12241,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/2262750dc1022c56d2c79e8d865c00045881c57bcaca74810ae8adac35cfdf723ff7d6b3b0e95c85eb9a0cff90bb4b1e0af801bd703ce8c0a2e35ab14ff1babb + checksum: 10c0/4e32ee04bf655a8bd3b4aacf6ffc596ae9eb1b9ba27eef83f7002632ee75371f61516ae62250634a9eae4b2c8fc6f6982d9b182de260f6c11841841e6e2e7515 languageName: node linkType: hard @@ -11904,6 +12264,25 @@ __metadata: languageName: node linkType: hard +"react-remove-scroll@npm:2.6.0": + version: 2.6.0 + resolution: "react-remove-scroll@npm:2.6.0" + dependencies: + react-remove-scroll-bar: "npm:^2.3.6" + react-style-singleton: "npm:^2.2.1" + tslib: "npm:^2.1.0" + use-callback-ref: "npm:^1.3.0" + use-sidecar: "npm:^1.1.2" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/c5881c537477d986e8d25d2588a9b6f7fe1254e05946fb4f4b55baeead502b0e1875fc3c42bb6f82736772cd96a50266e41d84e3c4cd25e9525bdfe2d838e96d + languageName: node + linkType: hard + "react-router-dom@npm:^6.1.0": version: 6.3.0 resolution: "react-router-dom@npm:6.3.0" From e753f6667ebc6ccc3b6632b92def2fc09af12777 Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Mon, 18 Nov 2024 14:36:23 +0100 Subject: [PATCH 032/170] refactor: ToggleGroup usage to primitives --- package.json | 4 - src/containers/ImageEditor/ImageEditor.tsx | 106 +- yarn.lock | 1368 ++------------------ 3 files changed, 173 insertions(+), 1305 deletions(-) diff --git a/package.json b/package.json index 452deb1333..9565561a0b 100644 --- a/package.json +++ b/package.json @@ -100,10 +100,6 @@ "@ndla/ui": "^56.0.71-alpha.0", "@ndla/util": "^5.0.0-alpha.0", "@ndla/video-search": "^8.0.60-alpha.0", - "@radix-ui/react-dropdown-menu": "^2.1.2", - "@radix-ui/react-popover": "^1.0.3", - "@radix-ui/react-portal": "^1.0.3", - "@radix-ui/react-toolbar": "^1.0.4", "@tanstack/react-query": "5.7.2", "auth0-js": "^9.22.1", "compression": "^1.7.4", diff --git a/src/containers/ImageEditor/ImageEditor.tsx b/src/containers/ImageEditor/ImageEditor.tsx index e2e9bde818..e399c6ee2b 100644 --- a/src/containers/ImageEditor/ImageEditor.tsx +++ b/src/containers/ImageEditor/ImageEditor.tsx @@ -11,7 +11,6 @@ import { MouseEvent, useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { PercentCrop } from "react-image-crop"; import styled from "@emotion/styled"; -import { ToggleGroup, ToggleGroupItem } from "@radix-ui/react-toggle-group"; import { colors, spacing } from "@ndla/core"; import { AlignCenter, @@ -25,6 +24,7 @@ import { ImageXxSmall, PublicDomain, } from "@ndla/icons/editor"; +import { Button, IconButton, ToggleGroupItem, ToggleGroupRoot } from "@ndla/primitives"; import { IImageMetaInformationV3 } from "@ndla/types-backend/image-api"; import ImageTransformEditor from "./ImageTransformEditor"; import { FormField } from "../../components/FormField"; @@ -44,25 +44,6 @@ const StyledImageEditorEditMode = styled.div` background-color: ${colors.brand.grey}; `; -const StyledToggleGroupItem = styled(ToggleGroupItem)` - all: unset; - transition: color 200ms ease; - color: ${colors.brand.grey}; - display: flex; - align-items: center; - justify-content: center; - &:focus-visible, - &:hover, - &[data-state="on"] { - cursor: pointer; - color: ${colors.white}; - } - &[disabled] { - color: ${colors.brand.primary}; - cursor: not-allowed; - } -`; - const alignments = [ { value: "left", children: }, { value: "center", children: }, @@ -100,7 +81,7 @@ interface Props { image: IImageMetaInformationV3; } -const StyledToggleGroup = styled(ToggleGroup)` +const StyledToggleGroupRoot = styled(ToggleGroupRoot)` display: flex; justify-content: space-between; width: 100%; @@ -189,10 +170,10 @@ const ImageEditor = ({ language, image }: Props) => { {({ field, helpers }) => ( - { + { + const val = details.value[0]; helpers.setValue(val); if (val === "center") { setFieldValue("size", "full"); @@ -200,17 +181,20 @@ const ImageEditor = ({ language, image }: Props) => { }} > {alignments.map(({ value, children }) => ( - - {children} - + + {children} + + ))} - + )} @@ -218,24 +202,26 @@ const ImageEditor = ({ language, image }: Props) => { {({ field, helpers }) => ( - { - helpers.setValue(val); + { + helpers.setValue(details.value[0]); }} > {sizes.map(({ value, children }) => ( - - {children} - + + {children} + + ))} - + )} @@ -249,37 +235,49 @@ const ImageEditor = ({ language, image }: Props) => { onFocalPointChange={onFocalPointChange} /> - setEditType(val as StateProp)}> + setEditType(details.value[0] as StateProp)} + > {isModifiable && ( - - - + + + + )} {imageCancelButtonNeeded && ( - - {t(`imageEditor.remove.${editType}`)} - + + + )} {isModifiable && ( - - - + + + + + )} - + {editType === "crop" && ( - + setAspect(details.value[0])}> {aspects.map(({ label, aspect }) => ( - - {label} - + + + ))} - + )} diff --git a/yarn.lock b/yarn.lock index 4c2db39cc6..0f1da2a2e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -309,7 +309,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.7.6": +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.7.6": version: 7.24.5 resolution: "@babel/runtime@npm:7.24.5" dependencies: @@ -1697,7 +1697,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/dom@npm:1.6.11, @floating-ui/dom@npm:^1.2.7": +"@floating-ui/dom@npm:1.6.11": version: 1.6.11 resolution: "@floating-ui/dom@npm:1.6.11" dependencies: @@ -1707,18 +1707,6 @@ __metadata: languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.0": - version: 2.0.0 - resolution: "@floating-ui/react-dom@npm:2.0.0" - dependencies: - "@floating-ui/dom": "npm:^1.2.7" - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 10c0/57be5b9547b5d65f7b475923c2844fabf1b0aa0fe4cbdf1e36f673389ac19e5ffa045a186d3cb4364256482d8b408eee8018fb0208793a0bb8d925d8eae9cd7f - languageName: node - linkType: hard - "@floating-ui/utils@npm:^0.2.7, @floating-ui/utils@npm:^0.2.8": version: 0.2.8 resolution: "@floating-ui/utils@npm:0.2.8" @@ -2269,1165 +2257,171 @@ __metadata: "@pandacss/generator@npm:0.46.1": version: 0.46.1 - resolution: "@pandacss/generator@npm:0.46.1" - dependencies: - "@pandacss/core": "npm:0.46.1" - "@pandacss/is-valid-prop": "npm:^0.46.1" - "@pandacss/logger": "npm:0.46.1" - "@pandacss/shared": "npm:0.46.1" - "@pandacss/token-dictionary": "npm:0.46.1" - "@pandacss/types": "npm:0.46.1" - javascript-stringify: "npm:2.1.0" - outdent: "npm: ^0.8.0" - pluralize: "npm:8.0.0" - postcss: "npm:8.4.47" - ts-pattern: "npm:5.0.8" - checksum: 10c0/a7d6e69ee9fffb1404136a8db10e7e83cc4d5a03addfd8ed8e9c18e211b8848b52b39b97351b21d086861e0c3db4bfa30a6d75ab2d947b29c594dd8ac9315fa7 - languageName: node - linkType: hard - -"@pandacss/is-valid-prop@npm:^0.46.1": - version: 0.46.1 - resolution: "@pandacss/is-valid-prop@npm:0.46.1" - checksum: 10c0/b920ce153793925ed57b83dfe1c70f7d4d27bcc0ce47dbfceed7154d3a33ec6a39c5e51797e4b8cb97495b7d4a6b85e6dfe5441647be7a6e33d3f87368f6095d - languageName: node - linkType: hard - -"@pandacss/logger@npm:0.46.1, @pandacss/logger@npm:^0.46.1": - version: 0.46.1 - resolution: "@pandacss/logger@npm:0.46.1" - dependencies: - "@pandacss/types": "npm:0.46.1" - kleur: "npm:4.1.5" - checksum: 10c0/93642251de28070dcbb2e4c99f635e312ad48f3bcc3f203c4b39680f5b0ded6966e8498b0722f5b187f505f12b36a80cd53116ce6f4aae6955842c1e053ee48c - languageName: node - linkType: hard - -"@pandacss/node@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/node@npm:0.46.1" - dependencies: - "@pandacss/config": "npm:0.46.1" - "@pandacss/core": "npm:0.46.1" - "@pandacss/extractor": "npm:0.46.1" - "@pandacss/generator": "npm:0.46.1" - "@pandacss/logger": "npm:0.46.1" - "@pandacss/parser": "npm:0.46.1" - "@pandacss/shared": "npm:0.46.1" - "@pandacss/token-dictionary": "npm:0.46.1" - "@pandacss/types": "npm:0.46.1" - browserslist: "npm:4.23.3" - chokidar: "npm:3.6.0" - fast-glob: "npm:3.3.2" - file-size: "npm:1.0.0" - filesize: "npm:10.1.6" - fs-extra: "npm:11.2.0" - glob-parent: "npm:6.0.2" - is-glob: "npm:4.0.3" - lodash.merge: "npm:4.6.2" - look-it-up: "npm:2.1.0" - outdent: "npm: ^0.8.0" - package-manager-detector: "npm:0.1.0" - perfect-debounce: "npm:1.0.0" - pkg-types: "npm:1.0.3" - pluralize: "npm:8.0.0" - postcss: "npm:8.4.47" - prettier: "npm:3.2.5" - ts-morph: "npm:21.0.1" - ts-pattern: "npm:5.0.8" - tsconfck: "npm:3.0.2" - checksum: 10c0/1c7b2fb28e9b121880b36e64e824615a16d253eaf9304ca79764dea87fd421bd680e8cace1cc1103e440c20e8cdbf3b5affecbb95a29bb192a3dd51f9d71785e - languageName: node - linkType: hard - -"@pandacss/parser@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/parser@npm:0.46.1" - dependencies: - "@pandacss/config": "npm:^0.46.1" - "@pandacss/core": "npm:^0.46.1" - "@pandacss/extractor": "npm:0.46.1" - "@pandacss/logger": "npm:0.46.1" - "@pandacss/shared": "npm:0.46.1" - "@pandacss/types": "npm:0.46.1" - "@vue/compiler-sfc": "npm:3.4.19" - magic-string: "npm:0.30.11" - ts-morph: "npm:21.0.1" - ts-pattern: "npm:5.0.8" - checksum: 10c0/bc109d10e956349295b02ad6002f430f42074594f3590833ecf72d450b86b28960a665864ee31345391e56a179c500f243379d31f7f819abbd7fc3ae3b6e5090 - languageName: node - linkType: hard - -"@pandacss/postcss@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/postcss@npm:0.46.1" - dependencies: - "@pandacss/node": "npm:0.46.1" - postcss: "npm:8.4.47" - checksum: 10c0/6a7901cb92aac2486324878358df03b703b5732dbddc3ca41b275ac9edbc97fc2ab0ad5945f7d46e2c3db43803b7a3a4e8c674ba863c83d672e6f53b08ac54e2 - languageName: node - linkType: hard - -"@pandacss/preset-base@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/preset-base@npm:0.46.1" - dependencies: - "@pandacss/types": "npm:0.46.1" - checksum: 10c0/b882c649e4beab52208f56e9f3adbe7d6f377d6cc3c1617d1352ef3104cdcab9294751509749aa22c20109596c369e0cf67d261eb287ef749f97845934a9888a - languageName: node - linkType: hard - -"@pandacss/preset-panda@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/preset-panda@npm:0.46.1" - dependencies: - "@pandacss/types": "npm:0.46.1" - checksum: 10c0/9bb1aa8bf79e59935dfa6a336ab17c0609feee9c09b8aceee851199c7ca7f03695d5be610c581fabffb82b9a81e4e51ef62c8f3125b328ea16950199c4d2777c - languageName: node - linkType: hard - -"@pandacss/shared@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/shared@npm:0.46.1" - checksum: 10c0/9780ecaf158a5f74a793df7b3261122e784e271cd0be37e205c652f0b6fdd8aaece3388ed574d8975ccb900fae70e8c1c836875d4ca08cb38d94539da17c2eb9 - languageName: node - linkType: hard - -"@pandacss/token-dictionary@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/token-dictionary@npm:0.46.1" - dependencies: - "@pandacss/logger": "npm:^0.46.1" - "@pandacss/shared": "npm:0.46.1" - "@pandacss/types": "npm:0.46.1" - ts-pattern: "npm:5.0.8" - checksum: 10c0/e7635d639e3105e0c90bf72ee21a1b2ebf3dae554f03f69d999785165477f2b4780a6064e5b3c37e979fe5382e1b84d6c9baa1dc59751d883cc571fb2de5c14a - languageName: node - linkType: hard - -"@pandacss/types@npm:0.46.1": - version: 0.46.1 - resolution: "@pandacss/types@npm:0.46.1" - checksum: 10c0/950ee13051a7ee1619beed582917c44874ad5f6013deca92db3d9b6e6500cf01710558b97d77e9e1a5735b2199e2ee3643633dd3ef781437fd62f84efa876127 - languageName: node - linkType: hard - -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd - languageName: node - linkType: hard - -"@playwright/test@npm:^1.42.0": - version: 1.42.0 - resolution: "@playwright/test@npm:1.42.0" - dependencies: - playwright: "npm:1.42.0" - bin: - playwright: cli.js - checksum: 10c0/1505544fd4962cc9463c2e0d21958507b4b23ecb835ef19d81a97ae01cda9030585dc321263486cce4d1eac53724615b7b3ec41a94b6c1a54a2b7ed01157de60 - languageName: node - linkType: hard - -"@polka/url@npm:^1.0.0-next.24": - version: 1.0.0-next.24 - resolution: "@polka/url@npm:1.0.0-next.24" - checksum: 10c0/97d98fa911857158514457bedad8c36084c1f608302458f580ab300a25c3abf456d1d54fcf2ea7927464bee0858baf5e8e5b374b95c3375b9eb3784d81411ebd - languageName: node - linkType: hard - -"@radix-ui/primitive@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/primitive@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - checksum: 10c0/912216455537db3ca77f3e7f70174fb2b454fbd4a37a0acb7cfadad9ab6131abdfb787472242574460a3c301edf45738340cc84f6717982710082840fde7d916 - languageName: node - linkType: hard - -"@radix-ui/primitive@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/primitive@npm:1.1.0" - checksum: 10c0/1dcc8b5401799416ff8bdb15c7189b4536c193220ad8fd348a48b88f804ee38cec7bd03e2b9641f7da24610e2f61f23a306911ce883af92c4e8c1abac634cb61 - languageName: node - linkType: hard - -"@radix-ui/react-arrow@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-arrow@npm:1.0.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-primitive": "npm:1.0.3" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/c931f6d7e0bac50fd1654a0303a303aff74a68a13a33a851a43a7c88677b53a92ca6557920b9105144a3002f899ce888437d20ddd7803a5c716edac99587626d - languageName: node - linkType: hard - -"@radix-ui/react-arrow@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-arrow@npm:1.1.0" - dependencies: - "@radix-ui/react-primitive": "npm:2.0.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/cbe059dfa5a9c1677478d363bb5fd75b0c7a08221d0ac7f8e7b9aec9dbae9754f6a3518218cf63e4ed53df6c36d193c8d2618d03433a37aa0cb7ee77a60a591f - languageName: node - linkType: hard - -"@radix-ui/react-collection@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-collection@npm:1.0.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-slot": "npm:1.0.2" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/cefa56383d7451ca79e4bd5a29aaeef6c205a04297213efd149aaead82fc8cde4fb8298e20e6b3613e5696e43f814fb4489805428f6604834fb31f73c6725fa8 - languageName: node - linkType: hard - -"@radix-ui/react-collection@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-collection@npm:1.1.0" - dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-slot": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/fecb9f0871c827070a8794b39c7379fdc7d0855c4b05804f0b395eef39c37b2c2b6779865d6cb35d3bc74b6b380107bd8b3754d1730a34ea88913e6cd0eb84d4 - languageName: node - linkType: hard - -"@radix-ui/react-compose-refs@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-compose-refs@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/be06f8dab35b5a1bffa7a5982fb26218ddade1acb751288333e3b89d7b4a7dfb5a6371be83876dac0ec2ebe0866d295e8618b778608e1965342986ea448040ec - languageName: node - linkType: hard - -"@radix-ui/react-compose-refs@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-compose-refs@npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/7e18706084397d9458ca3473d8565b10691da06f6499a78edbcc4bd72cde08f62e91120658d17d58c19fc39d6b1dffe0133cc4535c8f5fce470abd478f6107e5 - languageName: node - linkType: hard - -"@radix-ui/react-context@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-context@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/3de5761b32cc70cd61715527f29d8c699c01ab28c195ced972ccbc7025763a373a68f18c9f948c7a7b922e469fd2df7fee5f7536e3f7bad44ffc06d959359333 - languageName: node - linkType: hard - -"@radix-ui/react-context@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-context@npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/c843980f568cc61b512708863ec84c42a02e0f88359b22ad1c0e290cea3e6d7618eccbd2cd37bd974fadaa7636cbed5bda27553722e61197eb53852eaa34f1bb - languageName: node - linkType: hard - -"@radix-ui/react-context@npm:1.1.1": - version: 1.1.1 - resolution: "@radix-ui/react-context@npm:1.1.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/fc4ace9d79d7954c715ade765e06c95d7e1b12a63a536bcbe842fb904f03f88fc5bd6e38d44bd23243d37a270b4c44380fedddaeeae2d274f0b898a20665aba2 - languageName: node - linkType: hard - -"@radix-ui/react-direction@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-direction@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/b1a45b4d1d5070ca3b5864b920f6c6210c962bdb519abb62b38b1baef9d06737dc3d8ecdb61860b7504a735235a539652f5977c7299ec021da84e6b0f64d988a - languageName: node - linkType: hard - -"@radix-ui/react-direction@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-direction@npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/eb07d8cc3ae2388b824e0a11ae0e3b71fb0c49972b506e249cec9f27a5b7ef4305ee668c98b674833c92e842163549a83beb0a197dec1ec65774bdeeb61f932c - languageName: node - linkType: hard - -"@radix-ui/react-dismissable-layer@npm:1.0.5": - version: 1.0.5 - resolution: "@radix-ui/react-dismissable-layer@npm:1.0.5" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - "@radix-ui/react-use-escape-keydown": "npm:1.0.3" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/7e4308867aecfb07b506330c1964d94a52247ab9453725613cd326762aa13e483423c250f107219c131b0449600eb8d1576ce3159c2b96e8c978f75e46062cb2 - languageName: node - linkType: hard - -"@radix-ui/react-dismissable-layer@npm:1.1.1": - version: 1.1.1 - resolution: "@radix-ui/react-dismissable-layer@npm:1.1.1" - dependencies: - "@radix-ui/primitive": "npm:1.1.0" - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - "@radix-ui/react-use-escape-keydown": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/637f8d55437bd2269d5aa9fa48e869eade31082cd950b5efcc5f0d9ed016b46feb7fcfcc115ba9972dba68c4686b57873d84aca67ece76ab77463e7de995f6da - languageName: node - linkType: hard - -"@radix-ui/react-dropdown-menu@npm:^2.1.2": - version: 2.1.2 - resolution: "@radix-ui/react-dropdown-menu@npm:2.1.2" - dependencies: - "@radix-ui/primitive": "npm:1.1.0" - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.1" - "@radix-ui/react-id": "npm:1.1.0" - "@radix-ui/react-menu": "npm:2.1.2" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-controllable-state": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/28e84cb116a34c3a73cd9be774170fc920fad6254c1ce285e8e3d86e33c02011229adc5590e385a42106b41bced23e0a482e884e6894e37f68d7e87c76171279 - languageName: node - linkType: hard - -"@radix-ui/react-focus-guards@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-focus-guards@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/d5fd4e5aa9d9a87c8ad490b3b4992d6f1d9eddf18e56df2a2bcf8744c4332b275d73377fd193df3e6ba0ad9608dc497709beca5c64de2b834d5f5350b3c9a272 - languageName: node - linkType: hard - -"@radix-ui/react-focus-guards@npm:1.1.1": - version: 1.1.1 - resolution: "@radix-ui/react-focus-guards@npm:1.1.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/2e99750ca593083a530542a185d656b45b100752353a7a193a67566e3c256414a76fa9171d152f8c0167b8d6c1fdf62b2e07750d7af2974bf8ef39eb204aa537 - languageName: node - linkType: hard - -"@radix-ui/react-focus-scope@npm:1.0.4": - version: 1.0.4 - resolution: "@radix-ui/react-focus-scope@npm:1.0.4" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/2fce0bafcab4e16cf4ed7560bda40654223f3d0add6b231e1c607433030c14e6249818b444b7b58ee7a6ff6bbf8e192c9c81d22c3a5c88c2daade9d1f881b5be - languageName: node - linkType: hard - -"@radix-ui/react-focus-scope@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-focus-scope@npm:1.1.0" - dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/2593d4bbd4a3525624675ec1d5a591a44f015f43f449b99a5a33228159b83f445e8f1c6bc6f9f2011387abaeadd3df406623c08d4e795b7ae509795652a1d069 - languageName: node - linkType: hard - -"@radix-ui/react-id@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-id@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-use-layout-effect": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/e2859ca58bea171c956098ace7ecf615cf9432f58a118b779a14720746b3adcf0351c36c75de131548672d3cd290ca238198acbd33b88dc4706f98312e9317ad - languageName: node - linkType: hard - -"@radix-ui/react-id@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-id@npm:1.1.0" - dependencies: - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/acf13e29e51ee96336837fc0cfecc306328b20b0e0070f6f0f7aa7a621ded4a1ee5537cfad58456f64bae76caa7f8769231e88dc7dc106197347ee433c275a79 - languageName: node - linkType: hard - -"@radix-ui/react-menu@npm:2.1.2": - version: 2.1.2 - resolution: "@radix-ui/react-menu@npm:2.1.2" - dependencies: - "@radix-ui/primitive": "npm:1.1.0" - "@radix-ui/react-collection": "npm:1.1.0" - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.1" - "@radix-ui/react-direction": "npm:1.1.0" - "@radix-ui/react-dismissable-layer": "npm:1.1.1" - "@radix-ui/react-focus-guards": "npm:1.1.1" - "@radix-ui/react-focus-scope": "npm:1.1.0" - "@radix-ui/react-id": "npm:1.1.0" - "@radix-ui/react-popper": "npm:1.2.0" - "@radix-ui/react-portal": "npm:1.1.2" - "@radix-ui/react-presence": "npm:1.1.1" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-roving-focus": "npm:1.1.0" - "@radix-ui/react-slot": "npm:1.1.0" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - aria-hidden: "npm:^1.1.1" - react-remove-scroll: "npm:2.6.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/4259f6fbc63048d58bffab443abda9b56ea6b0a28f1e4ae91787a360b9a31e7604de06c8fc70be861c1aaa7abff2858c9314aa3fffbc375c27b0c9aa219a51af - languageName: node - linkType: hard - -"@radix-ui/react-popover@npm:^1.0.3": - version: 1.0.7 - resolution: "@radix-ui/react-popover@npm:1.0.7" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-dismissable-layer": "npm:1.0.5" - "@radix-ui/react-focus-guards": "npm:1.0.1" - "@radix-ui/react-focus-scope": "npm:1.0.4" - "@radix-ui/react-id": "npm:1.0.1" - "@radix-ui/react-popper": "npm:1.1.3" - "@radix-ui/react-portal": "npm:1.0.4" - "@radix-ui/react-presence": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-slot": "npm:1.0.2" - "@radix-ui/react-use-controllable-state": "npm:1.0.1" - aria-hidden: "npm:^1.1.1" - react-remove-scroll: "npm:2.5.5" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/ed7abbd61df1e15d62072e214fafbdc4e31942e0ce49665f2045d8279944a0a37762bcd70a36389ed9e43c95797d5acb57f6f5ca5a15b688b1928cfc2b9ce196 - languageName: node - linkType: hard - -"@radix-ui/react-popper@npm:1.1.3": - version: 1.1.3 - resolution: "@radix-ui/react-popper@npm:1.1.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@floating-ui/react-dom": "npm:^2.0.0" - "@radix-ui/react-arrow": "npm:1.0.3" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - "@radix-ui/react-use-layout-effect": "npm:1.0.1" - "@radix-ui/react-use-rect": "npm:1.0.1" - "@radix-ui/react-use-size": "npm:1.0.1" - "@radix-ui/rect": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/a38c374ec65dd8d7c604af7151e96faec1743828d859dc4892e720c1803a7e1562add26aec2ddf2091defae4e15d989c028032ea481419e38c4693b3f12545c3 - languageName: node - linkType: hard - -"@radix-ui/react-popper@npm:1.2.0": - version: 1.2.0 - resolution: "@radix-ui/react-popper@npm:1.2.0" - dependencies: - "@floating-ui/react-dom": "npm:^2.0.0" - "@radix-ui/react-arrow": "npm:1.1.0" - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - "@radix-ui/react-use-rect": "npm:1.1.0" - "@radix-ui/react-use-size": "npm:1.1.0" - "@radix-ui/rect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/a78ea534b9822d07153fff0895b6cdf742e7213782b140b3ab94a76df0ca70e6001925aea946e99ca680fc63a7fcca49c1d62e8dc5a2f651692fba3541e180c0 - languageName: node - linkType: hard - -"@radix-ui/react-portal@npm:1.0.4": - version: 1.0.4 - resolution: "@radix-ui/react-portal@npm:1.0.4" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-primitive": "npm:1.0.3" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/fed32f8148b833fe852fb5e2f859979ffdf2fb9a9ef46583b9b52915d764ad36ba5c958a64e61d23395628ccc09d678229ee94cd112941e8fe2575021f820c29 - languageName: node - linkType: hard - -"@radix-ui/react-portal@npm:1.1.2, @radix-ui/react-portal@npm:^1.0.3": - version: 1.1.2 - resolution: "@radix-ui/react-portal@npm:1.1.2" - dependencies: - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/836967330893b16b85371775ed1a59e038ce99189f4851cfa976bde2710d704c2a9e49e0a5206e7ac3fcf8a67ddd2d126b8352a88f295d6ef49d04e269736ed1 - languageName: node - linkType: hard - -"@radix-ui/react-presence@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-presence@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-use-layout-effect": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/90780618b265fe794a8f1ddaa5bfd3c71a1127fa79330a14d32722e6265b44452a9dd36efe4e769129d33e57f979f6b8713e2cbf2e2755326aa3b0f337185b6e - languageName: node - linkType: hard - -"@radix-ui/react-presence@npm:1.1.1": - version: 1.1.1 - resolution: "@radix-ui/react-presence@npm:1.1.1" - dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/777cda0406450ff5ca0e49235e486237723323d046a3382e35a0e78eededccfc95a76a9b5fecd7404dac793264762f4bc10111af1e08f8cc2d4d571d7971220e - languageName: node - linkType: hard - -"@radix-ui/react-primitive@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-primitive@npm:1.0.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-slot": "npm:1.0.2" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/67a66ff8898a5e7739eda228ab6f5ce808858da1dce967014138d87e72b6bbfc93dc1467c706d98d1a2b93bf0b6e09233d1a24d31c78227b078444c1a69c42be - languageName: node - linkType: hard - -"@radix-ui/react-primitive@npm:2.0.0": - version: 2.0.0 - resolution: "@radix-ui/react-primitive@npm:2.0.0" - dependencies: - "@radix-ui/react-slot": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/00cb6ca499252ca848c299212ba6976171cea7608b10b3f9a9639d6732dea2df1197ba0d97c001a4fdb29313c3e7fc2a490f6245dd3579617a0ffd85ae964fdd - languageName: node - linkType: hard - -"@radix-ui/react-roving-focus@npm:1.0.4": - version: 1.0.4 - resolution: "@radix-ui/react-roving-focus@npm:1.0.4" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-collection": "npm:1.0.3" - "@radix-ui/react-compose-refs": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-direction": "npm:1.0.1" - "@radix-ui/react-id": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - "@radix-ui/react-use-controllable-state": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/61e3ddfd1647e64fba855434ff41e8e7ba707244fe8841f78c450fbdce525383b64259279475615d030dbf1625cbffd8eeebee72d91bf6978794f5dbcf887fc0 - languageName: node - linkType: hard - -"@radix-ui/react-roving-focus@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-roving-focus@npm:1.1.0" - dependencies: - "@radix-ui/primitive": "npm:1.1.0" - "@radix-ui/react-collection": "npm:1.1.0" - "@radix-ui/react-compose-refs": "npm:1.1.0" - "@radix-ui/react-context": "npm:1.1.0" - "@radix-ui/react-direction": "npm:1.1.0" - "@radix-ui/react-id": "npm:1.1.0" - "@radix-ui/react-primitive": "npm:2.0.0" - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - "@radix-ui/react-use-controllable-state": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/ce367d3033a12d639a8d445d2efa090aa4bc5a78125be568f8c8e4e59f30afd51b585a90031ec18cdba19afbaf1974633dbc0c2c3d2a14d9eb1bfea2ddbe5369 - languageName: node - linkType: hard - -"@radix-ui/react-separator@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-separator@npm:1.0.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-primitive": "npm:1.0.3" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/87bcde47343f2bc4439a0dc34381f557905d9b3c1e8c5a0d32ceea62a8ef84f3abf671c5cb29309fc87759ad41d39af619ba546cf54109d64c8746e3ca683de3 - languageName: node - linkType: hard - -"@radix-ui/react-slot@npm:1.0.2": - version: 1.0.2 - resolution: "@radix-ui/react-slot@npm:1.0.2" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-compose-refs": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/3af6ea4891e6fa8091e666802adffe7718b3cd390a10fa9229a5f40f8efded9f3918ea01b046103d93923d41cc32119505ebb6bde76cad07a87b6cf4f2119347 - languageName: node - linkType: hard - -"@radix-ui/react-slot@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-slot@npm:1.1.0" - dependencies: - "@radix-ui/react-compose-refs": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/a2e8bfb70c440506dd84a1a274f9a8bc433cca37ceae275e53552c9122612e3837744d7fc6f113d6ef1a11491aa914f4add71d76de41cb6d4db72547a8e261ae - languageName: node - linkType: hard - -"@radix-ui/react-toggle-group@npm:1.0.4": - version: 1.0.4 - resolution: "@radix-ui/react-toggle-group@npm:1.0.4" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-direction": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-roving-focus": "npm:1.0.4" - "@radix-ui/react-toggle": "npm:1.0.3" - "@radix-ui/react-use-controllable-state": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/4f4761965022759ac0950ac026029b64049e1f18ef07a01ddde788b7606efcb262c9ae3a418de0c0756bf7285182ed0d268502c6f17ba86d2ff27eee5507bbf7 - languageName: node - linkType: hard - -"@radix-ui/react-toggle@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-toggle@npm:1.0.3" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-use-controllable-state": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/9b487dad213ea7e70b0aa205e7c6f790a6f2bf394c39912e22dbe003403fd0d24a41c2efd31695fc31ab7bac286f28253dbb2fc5202cacd572ebf909f1fdc86c - languageName: node - linkType: hard - -"@radix-ui/react-toolbar@npm:^1.0.4": - version: 1.0.4 - resolution: "@radix-ui/react-toolbar@npm:1.0.4" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/primitive": "npm:1.0.1" - "@radix-ui/react-context": "npm:1.0.1" - "@radix-ui/react-direction": "npm:1.0.1" - "@radix-ui/react-primitive": "npm:1.0.3" - "@radix-ui/react-roving-focus": "npm:1.0.4" - "@radix-ui/react-separator": "npm:1.0.3" - "@radix-ui/react-toggle-group": "npm:1.0.4" - peerDependencies: - "@types/react": "*" - "@types/react-dom": "*" - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/3ed7ebe22ef2e8369e08bb59776671a7b8c413628249c338b8db86b4b9ac40127b4201d5bd4a9c23ea1fd21464769b4fa427d3ebcda3a7fcdbd45b256b5a753a - languageName: node - linkType: hard - -"@radix-ui/react-use-callback-ref@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-use-callback-ref@npm:1.0.1" + resolution: "@pandacss/generator@npm:0.46.1" dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/331b432be1edc960ca148637ae6087220873ee828ceb13bd155926ef8f49e862812de5b379129f6aaefcd11be53715f3237e6caa9a33d9c0abfff43f3ba58938 + "@pandacss/core": "npm:0.46.1" + "@pandacss/is-valid-prop": "npm:^0.46.1" + "@pandacss/logger": "npm:0.46.1" + "@pandacss/shared": "npm:0.46.1" + "@pandacss/token-dictionary": "npm:0.46.1" + "@pandacss/types": "npm:0.46.1" + javascript-stringify: "npm:2.1.0" + outdent: "npm: ^0.8.0" + pluralize: "npm:8.0.0" + postcss: "npm:8.4.47" + ts-pattern: "npm:5.0.8" + checksum: 10c0/a7d6e69ee9fffb1404136a8db10e7e83cc4d5a03addfd8ed8e9c18e211b8848b52b39b97351b21d086861e0c3db4bfa30a6d75ab2d947b29c594dd8ac9315fa7 languageName: node linkType: hard -"@radix-ui/react-use-callback-ref@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/e954863f3baa151faf89ac052a5468b42650efca924417470efd1bd254b411a94c69c30de2fdbb90187b38cb984795978e12e30423dc41e4309d93d53b66d819 +"@pandacss/is-valid-prop@npm:^0.46.1": + version: 0.46.1 + resolution: "@pandacss/is-valid-prop@npm:0.46.1" + checksum: 10c0/b920ce153793925ed57b83dfe1c70f7d4d27bcc0ce47dbfceed7154d3a33ec6a39c5e51797e4b8cb97495b7d4a6b85e6dfe5441647be7a6e33d3f87368f6095d languageName: node linkType: hard -"@radix-ui/react-use-controllable-state@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-use-controllable-state@npm:1.0.1" +"@pandacss/logger@npm:0.46.1, @pandacss/logger@npm:^0.46.1": + version: 0.46.1 + resolution: "@pandacss/logger@npm:0.46.1" dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/29b069dbf09e48bca321af6272574ad0fc7283174e7d092731a10663fe00c0e6b4bde5e1b5ea67725fe48dcbe8026e7ff0d69d42891c62cbb9ca408498171fbe + "@pandacss/types": "npm:0.46.1" + kleur: "npm:4.1.5" + checksum: 10c0/93642251de28070dcbb2e4c99f635e312ad48f3bcc3f203c4b39680f5b0ded6966e8498b0722f5b187f505f12b36a80cd53116ce6f4aae6955842c1e053ee48c languageName: node linkType: hard -"@radix-ui/react-use-controllable-state@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" +"@pandacss/node@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/node@npm:0.46.1" dependencies: - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/2af883b5b25822ac226e60a6bfde647c0123a76345052a90219026059b3f7225844b2c13a9a16fba859c1cda5fb3d057f2a04503f71780e607516492db4eb3a1 + "@pandacss/config": "npm:0.46.1" + "@pandacss/core": "npm:0.46.1" + "@pandacss/extractor": "npm:0.46.1" + "@pandacss/generator": "npm:0.46.1" + "@pandacss/logger": "npm:0.46.1" + "@pandacss/parser": "npm:0.46.1" + "@pandacss/shared": "npm:0.46.1" + "@pandacss/token-dictionary": "npm:0.46.1" + "@pandacss/types": "npm:0.46.1" + browserslist: "npm:4.23.3" + chokidar: "npm:3.6.0" + fast-glob: "npm:3.3.2" + file-size: "npm:1.0.0" + filesize: "npm:10.1.6" + fs-extra: "npm:11.2.0" + glob-parent: "npm:6.0.2" + is-glob: "npm:4.0.3" + lodash.merge: "npm:4.6.2" + look-it-up: "npm:2.1.0" + outdent: "npm: ^0.8.0" + package-manager-detector: "npm:0.1.0" + perfect-debounce: "npm:1.0.0" + pkg-types: "npm:1.0.3" + pluralize: "npm:8.0.0" + postcss: "npm:8.4.47" + prettier: "npm:3.2.5" + ts-morph: "npm:21.0.1" + ts-pattern: "npm:5.0.8" + tsconfck: "npm:3.0.2" + checksum: 10c0/1c7b2fb28e9b121880b36e64e824615a16d253eaf9304ca79764dea87fd421bd680e8cace1cc1103e440c20e8cdbf3b5affecbb95a29bb192a3dd51f9d71785e languageName: node linkType: hard -"@radix-ui/react-use-escape-keydown@npm:1.0.3": - version: 1.0.3 - resolution: "@radix-ui/react-use-escape-keydown@npm:1.0.3" +"@pandacss/parser@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/parser@npm:0.46.1" dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-use-callback-ref": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/3c94c78902dcb40b60083ee2184614f45c95a189178f52d89323b467bd04bcf5fdb1bc4d43debecd7f0b572c3843c7e04edbcb56f40a4b4b43936fb2770fb8ad + "@pandacss/config": "npm:^0.46.1" + "@pandacss/core": "npm:^0.46.1" + "@pandacss/extractor": "npm:0.46.1" + "@pandacss/logger": "npm:0.46.1" + "@pandacss/shared": "npm:0.46.1" + "@pandacss/types": "npm:0.46.1" + "@vue/compiler-sfc": "npm:3.4.19" + magic-string: "npm:0.30.11" + ts-morph: "npm:21.0.1" + ts-pattern: "npm:5.0.8" + checksum: 10c0/bc109d10e956349295b02ad6002f430f42074594f3590833ecf72d450b86b28960a665864ee31345391e56a179c500f243379d31f7f819abbd7fc3ae3b6e5090 languageName: node linkType: hard -"@radix-ui/react-use-escape-keydown@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.0" +"@pandacss/postcss@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/postcss@npm:0.46.1" dependencies: - "@radix-ui/react-use-callback-ref": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/910fd696e5a0994b0e06b9cb68def8a865f47951a013ec240c77db2a9e1e726105602700ef5e5f01af49f2f18fe0e73164f9a9651021f28538ef8a30d91f3fbb + "@pandacss/node": "npm:0.46.1" + postcss: "npm:8.4.47" + checksum: 10c0/6a7901cb92aac2486324878358df03b703b5732dbddc3ca41b275ac9edbc97fc2ab0ad5945f7d46e2c3db43803b7a3a4e8c674ba863c83d672e6f53b08ac54e2 languageName: node linkType: hard -"@radix-ui/react-use-layout-effect@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-use-layout-effect@npm:1.0.1" +"@pandacss/preset-base@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/preset-base@npm:0.46.1" dependencies: - "@babel/runtime": "npm:^7.13.10" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/13cd0c38395c5838bc9a18238020d3bcf67fb340039e6d1cbf438be1b91d64cf6900b78121f3dc9219faeb40dcc7b523ce0f17e4a41631655690e5a30a40886a + "@pandacss/types": "npm:0.46.1" + checksum: 10c0/b882c649e4beab52208f56e9f3adbe7d6f377d6cc3c1617d1352ef3104cdcab9294751509749aa22c20109596c369e0cf67d261eb287ef749f97845934a9888a languageName: node linkType: hard -"@radix-ui/react-use-layout-effect@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/9bf87ece1845c038ed95863cfccf9d75f557c2400d606343bab0ab3192b9806b9840e6aa0a0333fdf3e83cf9982632852192f3e68d7d8367bc8c788dfdf8e62b +"@pandacss/preset-panda@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/preset-panda@npm:0.46.1" + dependencies: + "@pandacss/types": "npm:0.46.1" + checksum: 10c0/9bb1aa8bf79e59935dfa6a336ab17c0609feee9c09b8aceee851199c7ca7f03695d5be610c581fabffb82b9a81e4e51ef62c8f3125b328ea16950199c4d2777c languageName: node linkType: hard -"@radix-ui/react-use-rect@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-use-rect@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/rect": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/94c5ab31dfd3678c0cb77a30025e82b3a287577c1a8674b0d703a36d27434bc9c59790e0bebf57ed153f0b8e0d8c3b9675fc9787b9eac525a09abcda8fa9e7eb +"@pandacss/shared@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/shared@npm:0.46.1" + checksum: 10c0/9780ecaf158a5f74a793df7b3261122e784e271cd0be37e205c652f0b6fdd8aaece3388ed574d8975ccb900fae70e8c1c836875d4ca08cb38d94539da17c2eb9 languageName: node linkType: hard -"@radix-ui/react-use-rect@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-rect@npm:1.1.0" +"@pandacss/token-dictionary@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/token-dictionary@npm:0.46.1" dependencies: - "@radix-ui/rect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/c2e30150ab49e2cec238cda306fd748c3d47fb96dcff69a3b08e1d19108d80bac239d48f1747a25dadca614e3e967267d43b91e60ea59db2befbc7bea913ff84 + "@pandacss/logger": "npm:^0.46.1" + "@pandacss/shared": "npm:0.46.1" + "@pandacss/types": "npm:0.46.1" + ts-pattern: "npm:5.0.8" + checksum: 10c0/e7635d639e3105e0c90bf72ee21a1b2ebf3dae554f03f69d999785165477f2b4780a6064e5b3c37e979fe5382e1b84d6c9baa1dc59751d883cc571fb2de5c14a languageName: node linkType: hard -"@radix-ui/react-use-size@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/react-use-size@npm:1.0.1" - dependencies: - "@babel/runtime": "npm:^7.13.10" - "@radix-ui/react-use-layout-effect": "npm:1.0.1" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/b109a4b3781781c4dc641a1173f0a6fcb0b0f7b2d7cdba5848a46070c9fb4e518909a46c20a3c2efbc78737c64859c59ead837f2940e8c8394d1c503ef58773b +"@pandacss/types@npm:0.46.1": + version: 0.46.1 + resolution: "@pandacss/types@npm:0.46.1" + checksum: 10c0/950ee13051a7ee1619beed582917c44874ad5f6013deca92db3d9b6e6500cf01710558b97d77e9e1a5735b2199e2ee3643633dd3ef781437fd62f84efa876127 languageName: node linkType: hard -"@radix-ui/react-use-size@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/react-use-size@npm:1.1.0" - dependencies: - "@radix-ui/react-use-layout-effect": "npm:1.1.0" - peerDependencies: - "@types/react": "*" - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/4c8b89037597fdc1824d009e0c941b510c7c6c30f83024cc02c934edd748886786e7d9f36f57323b02ad29833e7fa7e8974d81969b4ab33d8f41661afa4f30a6 +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd languageName: node linkType: hard -"@radix-ui/rect@npm:1.0.1": - version: 1.0.1 - resolution: "@radix-ui/rect@npm:1.0.1" +"@playwright/test@npm:^1.42.0": + version: 1.42.0 + resolution: "@playwright/test@npm:1.42.0" dependencies: - "@babel/runtime": "npm:^7.13.10" - checksum: 10c0/4c5159661340acc31b11e1f2ebd87a1521d39bfa287544dd2cd75b399539a4b625d38a1501c90ceae21fcca18ed164b0c3735817ff140ae334098192c110e571 + playwright: "npm:1.42.0" + bin: + playwright: cli.js + checksum: 10c0/1505544fd4962cc9463c2e0d21958507b4b23ecb835ef19d81a97ae01cda9030585dc321263486cce4d1eac53724615b7b3ec41a94b6c1a54a2b7ed01157de60 languageName: node linkType: hard -"@radix-ui/rect@npm:1.1.0": - version: 1.1.0 - resolution: "@radix-ui/rect@npm:1.1.0" - checksum: 10c0/a26ff7f8708fb5f2f7949baad70a6b2a597d761ee4dd4aadaf1c1a33ea82ea23dfef6ce6366a08310c5d008cdd60b2e626e4ee03fa342bd5f246ddd9d427f6be +"@polka/url@npm:^1.0.0-next.24": + version: 1.0.0-next.24 + resolution: "@polka/url@npm:1.0.0-next.24" + checksum: 10c0/97d98fa911857158514457bedad8c36084c1f608302458f580ab300a25c3abf456d1d54fcf2ea7927464bee0858baf5e8e5b374b95c3375b9eb3784d81411ebd languageName: node linkType: hard @@ -5595,7 +4589,7 @@ __metadata: languageName: node linkType: hard -"aria-hidden@npm:1.2.4, aria-hidden@npm:^1.1.1": +"aria-hidden@npm:1.2.4": version: 1.2.4 resolution: "aria-hidden@npm:1.2.4" dependencies: @@ -6870,13 +5864,6 @@ __metadata: languageName: node linkType: hard -"detect-node-es@npm:^1.1.0": - version: 1.1.0 - resolution: "detect-node-es@npm:1.1.0" - checksum: 10c0/e562f00de23f10c27d7119e1af0e7388407eb4b06596a25f6d79a360094a109ff285de317f02b090faae093d314cf6e73ac3214f8a5bb3a0def5bece94557fbe - languageName: node - linkType: hard - "dezalgo@npm:^1.0.4": version: 1.0.4 resolution: "dezalgo@npm:1.0.4" @@ -7070,10 +6057,6 @@ __metadata: "@ndla/video-search": "npm:^8.0.60-alpha.0" "@pandacss/dev": "npm:^0.46.1" "@playwright/test": "npm:^1.42.0" - "@radix-ui/react-dropdown-menu": "npm:^2.1.2" - "@radix-ui/react-popover": "npm:^1.0.3" - "@radix-ui/react-portal": "npm:^1.0.3" - "@radix-ui/react-toolbar": "npm:^1.0.4" "@tanstack/react-query": "npm:5.7.2" "@tanstack/react-query-devtools": "npm:^5.7.2" "@testing-library/dom": "npm:^10.4.0" @@ -8762,13 +7745,6 @@ __metadata: languageName: node linkType: hard -"get-nonce@npm:^1.0.0": - version: 1.0.1 - resolution: "get-nonce@npm:1.0.1" - checksum: 10c0/2d7df55279060bf0568549e1ffc9b84bc32a32b7541675ca092dce56317cdd1a59a98dcc4072c9f6a980779440139a3221d7486f52c488e69dc0fd27b1efb162 - languageName: node - linkType: hard - "get-stream@npm:^5.0.0": version: 5.2.0 resolution: "get-stream@npm:5.2.0" @@ -12229,60 +11205,6 @@ __metadata: languageName: node linkType: hard -"react-remove-scroll-bar@npm:^2.3.3, react-remove-scroll-bar@npm:^2.3.6": - version: 2.3.6 - resolution: "react-remove-scroll-bar@npm:2.3.6" - dependencies: - react-style-singleton: "npm:^2.2.1" - tslib: "npm:^2.0.0" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/4e32ee04bf655a8bd3b4aacf6ffc596ae9eb1b9ba27eef83f7002632ee75371f61516ae62250634a9eae4b2c8fc6f6982d9b182de260f6c11841841e6e2e7515 - languageName: node - linkType: hard - -"react-remove-scroll@npm:2.5.5": - version: 2.5.5 - resolution: "react-remove-scroll@npm:2.5.5" - dependencies: - react-remove-scroll-bar: "npm:^2.3.3" - react-style-singleton: "npm:^2.2.1" - tslib: "npm:^2.1.0" - use-callback-ref: "npm:^1.3.0" - use-sidecar: "npm:^1.1.2" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/4952657e6a7b9d661d4ad4dfcef81b9c7fa493e35164abff99c35c0b27b3d172ef7ad70c09416dc44dd14ff2e6b38a5ec7da27e27e90a15cbad36b8fd2fd8054 - languageName: node - linkType: hard - -"react-remove-scroll@npm:2.6.0": - version: 2.6.0 - resolution: "react-remove-scroll@npm:2.6.0" - dependencies: - react-remove-scroll-bar: "npm:^2.3.6" - react-style-singleton: "npm:^2.2.1" - tslib: "npm:^2.1.0" - use-callback-ref: "npm:^1.3.0" - use-sidecar: "npm:^1.1.2" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/c5881c537477d986e8d25d2588a9b6f7fe1254e05946fb4f4b55baeead502b0e1875fc3c42bb6f82736772cd96a50266e41d84e3c4cd25e9525bdfe2d838e96d - languageName: node - linkType: hard - "react-router-dom@npm:^6.1.0": version: 6.3.0 resolution: "react-router-dom@npm:6.3.0" @@ -12317,23 +11239,6 @@ __metadata: languageName: node linkType: hard -"react-style-singleton@npm:^2.2.1": - version: 2.2.1 - resolution: "react-style-singleton@npm:2.2.1" - dependencies: - get-nonce: "npm:^1.0.0" - invariant: "npm:^2.2.4" - tslib: "npm:^2.0.0" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/6d66f3bdb65e1ec79089f80314da97c9a005087a04ee034255a5de129a4c0d9fd0bf99fa7bf642781ac2dc745ca687aae3de082bd8afdd0d117bc953241e15ad - languageName: node - linkType: hard - "react@npm:^18.3.1": version: 18.3.1 resolution: "react@npm:18.3.1" @@ -14065,37 +12970,6 @@ __metadata: languageName: node linkType: hard -"use-callback-ref@npm:^1.3.0": - version: 1.3.0 - resolution: "use-callback-ref@npm:1.3.0" - dependencies: - tslib: "npm:^2.0.0" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/8a0867ffd441f358c66d79567970a745cc78ac2f98840a81c1fa749a525e8716116c645497d886a815e1dcf40ad81a107ebd6a7d15fd9ab5925c44a994a1d89a - languageName: node - linkType: hard - -"use-sidecar@npm:^1.1.2": - version: 1.1.2 - resolution: "use-sidecar@npm:1.1.2" - dependencies: - detect-node-es: "npm:^1.1.0" - tslib: "npm:^2.0.0" - peerDependencies: - "@types/react": ^16.9.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/89f0018fd9aee1fc17c85ac18c4bf8944d460d453d0d0e04ddbc8eaddf3fa591e9c74a1f8a438a1bff368a7a2417fab380bdb3df899d2194c4375b0982736de0 - languageName: node - linkType: hard - "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" From 7827ce8bd3dc1cd02da0a2fa6bceeded8d14b083 Mon Sep 17 00:00:00 2001 From: Gunnar Velle Date: Thu, 21 Nov 2024 12:13:41 +0100 Subject: [PATCH 033/170] Display Bekreft rather than Slett when publishing tax version! --- src/containers/TaxonomyVersions/components/VersionForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/TaxonomyVersions/components/VersionForm.tsx b/src/containers/TaxonomyVersions/components/VersionForm.tsx index 8541269f7e..5ba68a9d18 100644 --- a/src/containers/TaxonomyVersions/components/VersionForm.tsx +++ b/src/containers/TaxonomyVersions/components/VersionForm.tsx @@ -191,7 +191,7 @@ const VersionForm = ({ version, existingVersions, onClose }: Props) => { }} variant="secondary" > - {t("alertModal.delete")} + {t("alertModal.continue")}
From b23426eacd307d8159732c95bae925d7a956a945 Mon Sep 17 00:00:00 2001 From: Jonas Carlsen Date: Thu, 21 Nov 2024 12:27:48 +0100 Subject: [PATCH 034/170] feat: render footer globally --- src/components/Footer.tsx | 110 ++++++++++++++++++ src/components/Page/Layout.tsx | 10 +- src/components/ResourcePage.tsx | 2 - src/containers/App/SearchPage.tsx | 2 - .../App/components/FooterWrapper.tsx | 103 ---------------- .../EditSubjectFrontpage/Subjectpage.tsx | 2 - src/containers/Login/Login.tsx | 2 - src/containers/Logout/Logout.tsx | 2 - src/containers/NdlaFilm/NdlaFilm.tsx | 2 - src/containers/NodeDiff/NodeDiffPage.tsx | 2 - .../StructurePage/StructureContainer.tsx | 2 - .../TaxonomyVersions/TaxonomyVersionsPage.tsx | 2 - src/containers/WelcomePage/WelcomePage.tsx | 2 - 13 files changed, 117 insertions(+), 126 deletions(-) create mode 100644 src/components/Footer.tsx delete mode 100644 src/containers/App/components/FooterWrapper.tsx diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx new file mode 100644 index 0000000000..21945b3fc9 --- /dev/null +++ b/src/components/Footer.tsx @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2016-present, NDLA. + * + * This source code is licensed under the GPLv3 license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { createListCollection } from "@ark-ui/react"; +import { PageContent, SelectContent, SelectLabel, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; +import { styled } from "@ndla/styled-system/jsx"; +import { GenericSelectItem, GenericSelectTrigger } from "./abstractions/Select"; +import { supportedLanguages } from "../i18n2"; +import { LocaleType } from "../interfaces"; + +export const FooterBlock = styled("footer", { + base: { + position: "relative", + background: "primary", + paddingBlock: "medium", + }, +}); + +const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { + base: { + width: "unset", + }, +}); + +const FooterContainer = styled("div", { + base: { + marginBlockStart: "medium", + }, +}); + +const LanguageSelectorWrapper = styled("div", { + base: { + display: "flex", + justifyContent: "center", + }, +}); + +const FooterTextWrapper = styled("div", { + base: { + alignSelf: "flex-end", + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + }, +}); + +const FooterContent = styled("div", { + base: { + display: "flex", + gap: "xsmall", + alignItems: "flex-end", + justifyContent: "flex-end", + }, +}); + +export const Footer = () => { + const { t, i18n } = useTranslation(); + + const supportedLanguagesCollection = useMemo( + () => + createListCollection({ + items: supportedLanguages, + itemToString: (item) => t(`languages.${item}`), + }), + [t], + ); + + return ( + + + + + + i18n.changeLanguage(details.value[0] as LocaleType)} + value={[i18n.language]} + > + {t("languages.prefixChangeLanguage")} + + {t("languages.prefixChangeLanguage")} + + + {supportedLanguages.map((lang) => ( + + {t(`languages.${lang}`)} + + ))} + + + + + {t("footer.info")} + + {t("footer.editorInChief")} Sigurd Trageton + + + + + + + ); +}; diff --git a/src/components/Page/Layout.tsx b/src/components/Page/Layout.tsx index 7701c57f64..5cabbf1ccf 100644 --- a/src/components/Page/Layout.tsx +++ b/src/components/Page/Layout.tsx @@ -10,6 +10,7 @@ import { CSSProperties, useMemo } from "react"; import { Outlet } from "react-router-dom"; import { useComponentSize } from "@ndla/hooks"; import { styled } from "@ndla/styled-system/jsx"; +import { Footer } from "../Footer"; const PageLayout = styled("div", { base: { @@ -24,8 +25,11 @@ export const Layout = () => { const { height } = useComponentSize("masthead"); const mastheadHeightVar = useMemo(() => ({ "--masthead-height": `${height}px` }) as CSSProperties, [height]); return ( - - - + <> + + + +
+ ); }; diff --git a/src/components/ResourcePage.tsx b/src/components/ResourcePage.tsx index e023a04e58..ff7664f46d 100644 --- a/src/components/ResourcePage.tsx +++ b/src/components/ResourcePage.tsx @@ -17,7 +17,6 @@ import { HelmetWithTracker } from "@ndla/tracker"; import { NynorskTranslateProvider } from "./NynorskTranslateProvider"; import { useWideArticle } from "./WideArticleEditorProvider"; import { MAX_PAGE_WIDTH, MAX_PAGE_WIDTH_WITH_COMMENTS } from "../constants"; -import Footer from "../containers/App/components/FooterWrapper"; import NotFoundPage from "../containers/NotFoundPage/NotFoundPage"; import { usePreviousLocation } from "../util/routeHelpers"; @@ -89,7 +88,6 @@ const ResourcePage = ({ } /> -
); }; diff --git a/src/containers/App/SearchPage.tsx b/src/containers/App/SearchPage.tsx index a376f2df65..bff49f79a6 100644 --- a/src/containers/App/SearchPage.tsx +++ b/src/containers/App/SearchPage.tsx @@ -13,7 +13,6 @@ import { Route, Routes } from "react-router-dom"; import { UseQueryResult } from "@tanstack/react-query"; import { List } from "@ndla/icons/action"; import { SearchMedia, SearchContent, SquareAudio } from "@ndla/icons/editor"; -import Footer from "./components/FooterWrapper"; import { SearchType } from "../../interfaces"; import { useSearchAudio, useSearchSeries } from "../../modules/audio/audioQueries"; import { useSearchImages } from "../../modules/image/imageQueries"; @@ -118,7 +117,6 @@ const SearchPage = () => { })} } /> -
); }; diff --git a/src/containers/App/components/FooterWrapper.tsx b/src/containers/App/components/FooterWrapper.tsx deleted file mode 100644 index dd3577f818..0000000000 --- a/src/containers/App/components/FooterWrapper.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2016-present, NDLA. - * - * This source code is licensed under the GPLv3 license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import { useMemo } from "react"; -import { useTranslation } from "react-i18next"; -import { createListCollection } from "@ark-ui/react"; -import emotionStyled from "@emotion/styled"; -import { spacing } from "@ndla/core"; -import { SelectContent, SelectLabel, SelectRoot, SelectValueText, Text } from "@ndla/primitives"; -import { styled } from "@ndla/styled-system/jsx"; -import { GenericSelectItem, GenericSelectTrigger } from "../../../components/abstractions/Select"; -import { supportedLanguages } from "../../../i18n2"; -import { LocaleType } from "../../../interfaces"; - -export const FooterBlock = styled("footer", { - base: { - position: "relative", - background: "primary", - paddingBlock: "medium", - paddingInline: "4xlarge", - }, -}); - -const StyledGenericSelectTrigger = styled(GenericSelectTrigger, { - base: { - width: "unset", - }, -}); - -interface Props { - showLocaleSelector?: boolean; -} - -const FooterContainer = emotionStyled.div` - margin-top: ${spacing.medium}; -`; - -const LanguageSelectorWrapper = emotionStyled.div` - display: flex; - justify-content: center; - width: 100%; -`; - -const FooterTextWrapper = emotionStyled.div` - align-self: flex-end; - display: flex; - flex-direction: column; - align-items: flex-end; -`; - -const FooterWrapper = ({ showLocaleSelector }: Props) => { - const { t, i18n } = useTranslation(); - - const supportedLanguagesCollection = useMemo( - () => - createListCollection({ - items: supportedLanguages, - itemToString: (item) => t(`languages.${item}`), - }), - [t], - ); - - return ( - - - {showLocaleSelector && ( - - i18n.changeLanguage(details.value[0] as LocaleType)} - value={[i18n.language]} - > - {t("languages.prefixChangeLanguage")} - - {t("languages.prefixChangeLanguage")} - - - {supportedLanguages.map((lang) => ( - - {t(`languages.${lang}`)} - - ))} - - - - )} - - {t("footer.info")} - - {t("footer.editorInChief")} Sigurd Trageton - - - - - ); -}; - -export default FooterWrapper; diff --git a/src/containers/EditSubjectFrontpage/Subjectpage.tsx b/src/containers/EditSubjectFrontpage/Subjectpage.tsx index bfaa931784..6998cb7b6c 100644 --- a/src/containers/EditSubjectFrontpage/Subjectpage.tsx +++ b/src/containers/EditSubjectFrontpage/Subjectpage.tsx @@ -12,7 +12,6 @@ import { OneColumn } from "@ndla/ui"; import CreateSubjectpage from "./CreateSubjectpage"; import EditSubjectpage from "./EditSubjectpage"; import { usePreviousLocation } from "../../util/routeHelpers"; -import Footer from "../App/components/FooterWrapper"; import NotFoundPage from "../NotFoundPage/NotFoundPage"; const Subjectpage = () => { @@ -30,7 +29,6 @@ const Subjectpage = () => { } /> -
); }; diff --git a/src/containers/Login/Login.tsx b/src/containers/Login/Login.tsx index b72e16719f..a52fd6edce 100644 --- a/src/containers/Login/Login.tsx +++ b/src/containers/Login/Login.tsx @@ -15,7 +15,6 @@ import { OneColumn } from "@ndla/ui"; import LoginFailure from "./LoginFailure"; import LoginProviders from "./LoginProviders"; import LoginSuccess from "./LoginSuccess"; -import Footer from "../App/components/FooterWrapper"; import { useSession } from "../Session/SessionProvider"; const StyledOneColumn = styled(OneColumn)` @@ -43,7 +42,6 @@ export const Login = () => { } /> -
); }; diff --git a/src/containers/Logout/Logout.tsx b/src/containers/Logout/Logout.tsx index 6b2517a417..5478c14ac0 100644 --- a/src/containers/Logout/Logout.tsx +++ b/src/containers/Logout/Logout.tsx @@ -13,7 +13,6 @@ import { OneColumn } from "@ndla/ui"; import LogoutFederated from "./LogoutFederated"; import LogoutProviders from "./LogoutProviders"; import LogoutSession from "./LogoutSession"; -import Footer from "../App/components/FooterWrapper"; const Logout = () => { const { t } = useTranslation(); @@ -29,7 +28,6 @@ const Logout = () => {
-