@commercetools/nimbus-mcp 0.1.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -14
- package/data/docs/route-manifest.json +10913 -0
- package/data/docs/routes/components-accessibility-visually-hidden.json +388 -0
- package/data/docs/routes/components-accessibility.json +34 -0
- package/data/docs/routes/components-buttons-button.json +715 -0
- package/data/docs/routes/components-buttons-icon-button.json +852 -0
- package/data/docs/routes/components-buttons-icon-toggle-button.json +594 -0
- package/data/docs/routes/components-buttons-split-button.json +670 -0
- package/data/docs/routes/components-buttons-toggle-button-group.json +722 -0
- package/data/docs/routes/components-buttons-toggle-button.json +689 -0
- package/data/docs/routes/components-buttons.json +36 -0
- package/data/docs/routes/components-data-display-badge.json +555 -0
- package/data/docs/routes/components-data-display-card.json +338 -0
- package/data/docs/routes/components-data-display-data-table.json +855 -0
- package/data/docs/routes/components-data-display-draggable-list.json +596 -0
- package/data/docs/routes/components-data-display-table.json +472 -0
- package/data/docs/routes/components-data-display-tag-group.json +535 -0
- package/data/docs/routes/components-data-display.json +34 -0
- package/data/docs/routes/components-feedback-alert.json +696 -0
- package/data/docs/routes/components-feedback-dialog.json +682 -0
- package/data/docs/routes/components-feedback-drawer.json +600 -0
- package/data/docs/routes/components-feedback-loading-spinner.json +415 -0
- package/data/docs/routes/components-feedback-progress-bar.json +661 -0
- package/data/docs/routes/components-feedback-toast.json +1040 -0
- package/data/docs/routes/components-feedback-tooltip.json +510 -0
- package/data/docs/routes/components-feedback.json +34 -0
- package/data/docs/routes/components-forms-field-errors.json +557 -0
- package/data/docs/routes/components-forms-form-field.json +848 -0
- package/data/docs/routes/components-forms-group.json +427 -0
- package/data/docs/routes/components-forms-localized-field.json +770 -0
- package/data/docs/routes/components-forms.json +37 -0
- package/data/docs/routes/components-inputs-calendar.json +611 -0
- package/data/docs/routes/components-inputs-checkbox.json +774 -0
- package/data/docs/routes/components-inputs-combo-box.json +761 -0
- package/data/docs/routes/components-inputs-date-input.json +628 -0
- package/data/docs/routes/components-inputs-date-picker.json +709 -0
- package/data/docs/routes/components-inputs-date-range-picker.json +599 -0
- package/data/docs/routes/components-inputs-money-input.json +721 -0
- package/data/docs/routes/components-inputs-multiline-text-input.json +611 -0
- package/data/docs/routes/components-inputs-number-input.json +647 -0
- package/data/docs/routes/components-inputs-password-input.json +576 -0
- package/data/docs/routes/components-inputs-radio-input.json +583 -0
- package/data/docs/routes/components-inputs-range-calendar.json +607 -0
- package/data/docs/routes/components-inputs-rich-text-input.json +599 -0
- package/data/docs/routes/components-inputs-scoped-search-input.json +570 -0
- package/data/docs/routes/components-inputs-search-input.json +588 -0
- package/data/docs/routes/components-inputs-select-input.json +960 -0
- package/data/docs/routes/components-inputs-switch.json +720 -0
- package/data/docs/routes/components-inputs-text-input.json +566 -0
- package/data/docs/routes/components-inputs-time-input.json +775 -0
- package/data/docs/routes/components-inputs.json +34 -0
- package/data/docs/routes/components-layout-box.json +501 -0
- package/data/docs/routes/components-layout-defaultpage.json +748 -0
- package/data/docs/routes/components-layout-flex.json +587 -0
- package/data/docs/routes/components-layout-grid.json +393 -0
- package/data/docs/routes/components-layout-modalpage.json +716 -0
- package/data/docs/routes/components-layout-pagecontent.json +673 -0
- package/data/docs/routes/components-layout-separator.json +461 -0
- package/data/docs/routes/components-layout-simple-grid.json +519 -0
- package/data/docs/routes/components-layout-spacer.json +573 -0
- package/data/docs/routes/components-layout-stack.json +481 -0
- package/data/docs/routes/components-layout.json +34 -0
- package/data/docs/routes/components-media-avatar.json +427 -0
- package/data/docs/routes/components-media-icon.json +663 -0
- package/data/docs/routes/components-media-image.json +511 -0
- package/data/docs/routes/components-media-inline-svg.json +586 -0
- package/data/docs/routes/components-media.json +34 -0
- package/data/docs/routes/components-navigation-accordion.json +643 -0
- package/data/docs/routes/components-navigation-collapsible-motion.json +628 -0
- package/data/docs/routes/components-navigation-link.json +554 -0
- package/data/docs/routes/components-navigation-menu.json +546 -0
- package/data/docs/routes/components-navigation-pagination.json +502 -0
- package/data/docs/routes/components-navigation-steps.json +629 -0
- package/data/docs/routes/components-navigation-tabnav.json +546 -0
- package/data/docs/routes/components-navigation-tabs.json +635 -0
- package/data/docs/routes/components-navigation-toolbar.json +549 -0
- package/data/docs/routes/components-navigation.json +34 -0
- package/data/docs/routes/components-typography-code.json +39 -0
- package/data/docs/routes/components-typography-heading.json +402 -0
- package/data/docs/routes/components-typography-kbd.json +399 -0
- package/data/docs/routes/components-typography-list.json +593 -0
- package/data/docs/routes/components-typography-text.json +444 -0
- package/data/docs/routes/components-typography.json +34 -0
- package/data/docs/routes/components-utilities-nimbus-i18n-provider.json +295 -0
- package/data/docs/routes/components-utilities-nimbus-provider.json +663 -0
- package/data/docs/routes/components-utilities.json +34 -0
- package/data/docs/routes/components.json +33 -0
- package/data/docs/routes/home-contribute-adrs-adr0001-consumer-component-apis.json +314 -0
- package/data/docs/routes/home-contribute-adrs-adr0002-compound-component-extraction.json +160 -0
- package/data/docs/routes/home-contribute-adrs-adr0003-component-lifecycle-states.json +460 -0
- package/data/docs/routes/home-contribute-adrs.json +205 -0
- package/data/docs/routes/home-contribute-development-setup.json +213 -0
- package/data/docs/routes/home-contribute-stats.json +36 -0
- package/data/docs/routes/home-contribute.json +36 -0
- package/data/docs/routes/home-design-tokens-aspect-ratios.json +36 -0
- package/data/docs/routes/home-design-tokens-borders.json +35 -0
- package/data/docs/routes/home-design-tokens-colors.json +157 -0
- package/data/docs/routes/home-design-tokens-other-animations.json +119 -0
- package/data/docs/routes/home-design-tokens-other-blurs.json +36 -0
- package/data/docs/routes/home-design-tokens-other-breakpoints.json +61 -0
- package/data/docs/routes/home-design-tokens-other-cursors.json +36 -0
- package/data/docs/routes/home-design-tokens-other-z-indices.json +39 -0
- package/data/docs/routes/home-design-tokens-other.json +35 -0
- package/data/docs/routes/home-design-tokens-radii.json +59 -0
- package/data/docs/routes/home-design-tokens-shadows.json +57 -0
- package/data/docs/routes/home-design-tokens-sizes.json +137 -0
- package/data/docs/routes/home-design-tokens-spacing.json +36 -0
- package/data/docs/routes/home-design-tokens-typography.json +184 -0
- package/data/docs/routes/home-design-tokens.json +34 -0
- package/data/docs/routes/home-getting-started-core-concepts.json +301 -0
- package/data/docs/routes/home-getting-started-installation.json +621 -0
- package/data/docs/routes/home-getting-started-mcp-server-overview.json +139 -0
- package/data/docs/routes/home-getting-started-mcp-server-setup.json +316 -0
- package/data/docs/routes/home-getting-started-release-process.json +294 -0
- package/data/docs/routes/home-getting-started-testing-setup.json +296 -0
- package/data/docs/routes/home-playground-markdown.json +638 -0
- package/data/docs/routes/home-playground-toc.json +169 -0
- package/data/docs/routes/home-playground.json +34 -0
- package/data/docs/routes/home-style-props-background.json +236 -0
- package/data/docs/routes/home-style-props-border.json +310 -0
- package/data/docs/routes/home-style-props-display.json +120 -0
- package/data/docs/routes/home-style-props-effects.json +116 -0
- package/data/docs/routes/home-style-props-filters.json +396 -0
- package/data/docs/routes/home-style-props-flex-and-grid.json +496 -0
- package/data/docs/routes/home-style-props-interactivity.json +356 -0
- package/data/docs/routes/home-style-props-layout.json +422 -0
- package/data/docs/routes/home-style-props-list.json +116 -0
- package/data/docs/routes/home-style-props-sizing.json +244 -0
- package/data/docs/routes/home-style-props-spacing.json +228 -0
- package/data/docs/routes/home-style-props-svg.json +96 -0
- package/data/docs/routes/home-style-props-tables.json +116 -0
- package/data/docs/routes/home-style-props-transforms.json +216 -0
- package/data/docs/routes/home-style-props-transitions.json +216 -0
- package/data/docs/routes/home-style-props-typography.json +536 -0
- package/data/docs/routes/home-style-props.json +33 -0
- package/data/docs/routes/home.json +32 -0
- package/data/docs/routes/hooks-usecopytoclipboard.json +76 -0
- package/data/docs/routes/hooks-usehotkeys.json +117 -0
- package/data/docs/routes/hooks.json +33 -0
- package/data/docs/routes/icons.json +32 -0
- package/data/docs/routes/patterns-fields-date-range-picker-field.json +393 -0
- package/data/docs/routes/patterns-fields-money-input-field.json +415 -0
- package/data/docs/routes/patterns-fields-multiline-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields-number-input-field.json +470 -0
- package/data/docs/routes/patterns-fields-password-input-field.json +319 -0
- package/data/docs/routes/patterns-fields-search-input-field.json +382 -0
- package/data/docs/routes/patterns-fields-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields.json +78 -0
- package/data/docs/routes/patterns.json +34 -0
- package/data/docs/search-index.json +1 -0
- package/data/docs/types/Accordion.json +12 -0
- package/data/docs/types/AccordionContent.json +286 -0
- package/data/docs/types/AccordionHeader.json +891 -0
- package/data/docs/types/AccordionHeaderRightContent.json +27 -0
- package/data/docs/types/AccordionItem.json +242 -0
- package/data/docs/types/AccordionRoot.json +162 -0
- package/data/docs/types/Alert.json +12 -0
- package/data/docs/types/AlertActions.json +11 -0
- package/data/docs/types/AlertDescription.json +118 -0
- package/data/docs/types/AlertDismissButton.json +937 -0
- package/data/docs/types/AlertRoot.json +42 -0
- package/data/docs/types/AlertTitle.json +118 -0
- package/data/docs/types/Avatar.json +125 -0
- package/data/docs/types/Badge.json +64 -0
- package/data/docs/types/Body.json +67 -0
- package/data/docs/types/Box.json +85 -0
- package/data/docs/types/Button.json +1015 -0
- package/data/docs/types/Calendar.json +565 -0
- package/data/docs/types/Caption.json +67 -0
- package/data/docs/types/Card.json +12 -0
- package/data/docs/types/CardContent.json +27 -0
- package/data/docs/types/CardHeader.json +27 -0
- package/data/docs/types/CardRoot.json +106 -0
- package/data/docs/types/Cell.json +227 -0
- package/data/docs/types/Checkbox.json +897 -0
- package/data/docs/types/Code.json +112 -0
- package/data/docs/types/CollapsibleMotionContent.json +35 -0
- package/data/docs/types/CollapsibleMotionRoot.json +99 -0
- package/data/docs/types/CollapsibleMotionTrigger.json +71 -0
- package/data/docs/types/Column.json +101 -0
- package/data/docs/types/ColumnGroup.json +101 -0
- package/data/docs/types/ColumnHeader.json +193 -0
- package/data/docs/types/ComboBoxListBox.json +751 -0
- package/data/docs/types/ComboBoxOption.json +672 -0
- package/data/docs/types/ComboBoxPopover.json +786 -0
- package/data/docs/types/ComboBoxRoot.json +747 -0
- package/data/docs/types/ComboBoxSection.json +277 -0
- package/data/docs/types/ComboBoxTrigger.json +70 -0
- package/data/docs/types/Content.json +33 -0
- package/data/docs/types/DataTable.json +596 -0
- package/data/docs/types/DataTableBody.json +223 -0
- package/data/docs/types/DataTableFooter.json +27 -0
- package/data/docs/types/DataTableHeader.json +269 -0
- package/data/docs/types/DataTableManager.json +11 -0
- package/data/docs/types/DataTableRoot.json +590 -0
- package/data/docs/types/DataTableTable.json +271 -0
- package/data/docs/types/DateInput.json +792 -0
- package/data/docs/types/DatePicker.json +700 -0
- package/data/docs/types/DateRangePicker.json +936 -0
- package/data/docs/types/DateRangePickerField.json +1047 -0
- package/data/docs/types/DefaultPage.json +12 -0
- package/data/docs/types/DefaultPageActions.json +27 -0
- package/data/docs/types/DefaultPageBackLink.json +213 -0
- package/data/docs/types/DefaultPageContent.json +27 -0
- package/data/docs/types/DefaultPageFooter.json +27 -0
- package/data/docs/types/DefaultPageHeader.json +27 -0
- package/data/docs/types/DefaultPageRoot.json +106 -0
- package/data/docs/types/DefaultPageSubtitle.json +27 -0
- package/data/docs/types/DefaultPageTabNav.json +28 -0
- package/data/docs/types/DefaultPageTitle.json +27 -0
- package/data/docs/types/DialogBody.json +27 -0
- package/data/docs/types/DialogCloseTrigger.json +939 -0
- package/data/docs/types/DialogContent.json +27 -0
- package/data/docs/types/DialogFooter.json +27 -0
- package/data/docs/types/DialogHeader.json +27 -0
- package/data/docs/types/DialogRoot.json +138 -0
- package/data/docs/types/DialogTitle.json +27 -0
- package/data/docs/types/DialogTrigger.json +80 -0
- package/data/docs/types/DraggableList.json +12 -0
- package/data/docs/types/DraggableListField.json +894 -0
- package/data/docs/types/DraggableListItem.json +574 -0
- package/data/docs/types/DraggableListRoot.json +745 -0
- package/data/docs/types/Drawer.json +12 -0
- package/data/docs/types/DrawerBody.json +27 -0
- package/data/docs/types/DrawerCloseTrigger.json +939 -0
- package/data/docs/types/DrawerContent.json +27 -0
- package/data/docs/types/DrawerFooter.json +27 -0
- package/data/docs/types/DrawerHeader.json +27 -0
- package/data/docs/types/DrawerRoot.json +142 -0
- package/data/docs/types/DrawerTitle.json +27 -0
- package/data/docs/types/DrawerTrigger.json +80 -0
- package/data/docs/types/FieldErrors.getBuiltInMessage.json +11 -0
- package/data/docs/types/FieldErrors.getCustomMessage.json +9 -0
- package/data/docs/types/FieldErrors.json +109 -0
- package/data/docs/types/Flex.json +238 -0
- package/data/docs/types/Footer.json +67 -0
- package/data/docs/types/FormFieldDescription.json +11 -0
- package/data/docs/types/FormFieldError.json +11 -0
- package/data/docs/types/FormFieldInfoBox.json +27 -0
- package/data/docs/types/FormFieldInput.json +11 -0
- package/data/docs/types/FormFieldLabel.json +11 -0
- package/data/docs/types/FormFieldRoot.json +148 -0
- package/data/docs/types/Grid.json +253 -0
- package/data/docs/types/GridProps.json +11 -0
- package/data/docs/types/Group.json +143 -0
- package/data/docs/types/Header.json +67 -0
- package/data/docs/types/Heading.json +109 -0
- package/data/docs/types/Icon.json +112 -0
- package/data/docs/types/IconButton.json +1019 -0
- package/data/docs/types/IconToggleButton.json +787 -0
- package/data/docs/types/Image.json +373 -0
- package/data/docs/types/Indicator.json +67 -0
- package/data/docs/types/InlineSvg.json +98 -0
- package/data/docs/types/Item.json +67 -0
- package/data/docs/types/Kbd.json +118 -0
- package/data/docs/types/Link.json +380 -0
- package/data/docs/types/List.json +12 -0
- package/data/docs/types/ListIndicator.json +70 -0
- package/data/docs/types/ListItem.json +70 -0
- package/data/docs/types/ListRoot.json +124 -0
- package/data/docs/types/LoadingSpinner.json +87 -0
- package/data/docs/types/LocalizedField.json +460 -0
- package/data/docs/types/LocalizedStringFormatter.json +9 -0
- package/data/docs/types/MakeElementFocusable.json +196 -0
- package/data/docs/types/MenuContent.json +111 -0
- package/data/docs/types/MenuItem.json +671 -0
- package/data/docs/types/MenuRoot.json +670 -0
- package/data/docs/types/MenuSection.json +364 -0
- package/data/docs/types/MenuSubmenu.json +111 -0
- package/data/docs/types/MenuSubmenuTrigger.json +67 -0
- package/data/docs/types/MenuTrigger.json +906 -0
- package/data/docs/types/ModalPage.json +12 -0
- package/data/docs/types/ModalPageActions.json +27 -0
- package/data/docs/types/ModalPageContent.json +27 -0
- package/data/docs/types/ModalPageFooter.json +27 -0
- package/data/docs/types/ModalPageHeader.json +27 -0
- package/data/docs/types/ModalPageRoot.json +87 -0
- package/data/docs/types/ModalPageSubtitle.json +27 -0
- package/data/docs/types/ModalPageTabNav.json +28 -0
- package/data/docs/types/ModalPageTitle.json +27 -0
- package/data/docs/types/ModalPageTopBar.json +57 -0
- package/data/docs/types/MoneyInput.isEmpty.json +40 -0
- package/data/docs/types/MoneyInput.json +282 -0
- package/data/docs/types/MoneyInputField.json +379 -0
- package/data/docs/types/MoneyInputFieldProps.json +9 -0
- package/data/docs/types/MultilineTextInput.json +1194 -0
- package/data/docs/types/MultilineTextInputField.json +1269 -0
- package/data/docs/types/MultilineTextInputFieldProps.json +9 -0
- package/data/docs/types/NimbusI18nProvider.json +42 -0
- package/data/docs/types/NimbusI18nProviderProps.json +9 -0
- package/data/docs/types/NimbusProvider.json +270 -0
- package/data/docs/types/NumberInput.json +952 -0
- package/data/docs/types/NumberInputField.json +1004 -0
- package/data/docs/types/NumberInputFieldProps.json +9 -0
- package/data/docs/types/PageContent.json +11 -0
- package/data/docs/types/PageContentColumn.json +99 -0
- package/data/docs/types/PageContentRoot.json +114 -0
- package/data/docs/types/Pagination.json +159 -0
- package/data/docs/types/PasswordInput.json +1120 -0
- package/data/docs/types/PasswordInputField.json +1216 -0
- package/data/docs/types/PasswordInputFieldProps.json +9 -0
- package/data/docs/types/ProgressBar.json +280 -0
- package/data/docs/types/RadioInputOption.json +550 -0
- package/data/docs/types/RadioInputRoot.json +514 -0
- package/data/docs/types/RangeCalendar.json +618 -0
- package/data/docs/types/RichTextInput.json +134 -0
- package/data/docs/types/Root.json +122 -0
- package/data/docs/types/Row.json +67 -0
- package/data/docs/types/ScopedSearchInput.isEmpty.json +40 -0
- package/data/docs/types/ScopedSearchInput.json +253 -0
- package/data/docs/types/ScrollArea.json +82 -0
- package/data/docs/types/SearchInput.json +1165 -0
- package/data/docs/types/SearchInputField.json +1240 -0
- package/data/docs/types/Select.json +12 -0
- package/data/docs/types/SelectOption.json +572 -0
- package/data/docs/types/SelectOptionGroup.json +215 -0
- package/data/docs/types/SelectOptions.json +693 -0
- package/data/docs/types/SelectRoot.json +926 -0
- package/data/docs/types/Separator.json +65 -0
- package/data/docs/types/SimpleGrid.json +291 -0
- package/data/docs/types/Spacer.json +27 -0
- package/data/docs/types/SpacerProps.json +9 -0
- package/data/docs/types/SplitButton.json +203 -0
- package/data/docs/types/Stack.json +144 -0
- package/data/docs/types/Steps.json +12 -0
- package/data/docs/types/StepsChangeDetails.json +9 -0
- package/data/docs/types/StepsCompletedContent.json +28 -0
- package/data/docs/types/StepsCompletedContentProps.json +9 -0
- package/data/docs/types/StepsContent.json +43 -0
- package/data/docs/types/StepsContentProps.json +9 -0
- package/data/docs/types/StepsDescription.json +28 -0
- package/data/docs/types/StepsDescriptionProps.json +9 -0
- package/data/docs/types/StepsIndicator.json +28 -0
- package/data/docs/types/StepsIndicatorProps.json +9 -0
- package/data/docs/types/StepsItem.json +43 -0
- package/data/docs/types/StepsItemProps.json +9 -0
- package/data/docs/types/StepsList.json +28 -0
- package/data/docs/types/StepsListProps.json +9 -0
- package/data/docs/types/StepsNextTrigger.json +62 -0
- package/data/docs/types/StepsNextTriggerProps.json +9 -0
- package/data/docs/types/StepsNumber.json +28 -0
- package/data/docs/types/StepsNumberProps.json +9 -0
- package/data/docs/types/StepsPrevTrigger.json +62 -0
- package/data/docs/types/StepsPrevTriggerProps.json +9 -0
- package/data/docs/types/StepsRoot.json +183 -0
- package/data/docs/types/StepsRootProps.json +11 -0
- package/data/docs/types/StepsSeparator.json +28 -0
- package/data/docs/types/StepsSeparatorProps.json +9 -0
- package/data/docs/types/StepsStatus.json +57 -0
- package/data/docs/types/StepsStatusProps.json +9 -0
- package/data/docs/types/StepsTitle.json +28 -0
- package/data/docs/types/StepsTitleProps.json +9 -0
- package/data/docs/types/StepsTrigger.json +47 -0
- package/data/docs/types/StepsTriggerProps.json +9 -0
- package/data/docs/types/Switch.json +371 -0
- package/data/docs/types/TabListProps.json +9 -0
- package/data/docs/types/TabNav.json +12 -0
- package/data/docs/types/TabNavItem.json +300 -0
- package/data/docs/types/TabNavItemProps.json +9 -0
- package/data/docs/types/TabNavProps.json +9 -0
- package/data/docs/types/TabNavRoot.json +80 -0
- package/data/docs/types/TabPanelProps.json +9 -0
- package/data/docs/types/TabPanelsProps.json +9 -0
- package/data/docs/types/TabProps.json +9 -0
- package/data/docs/types/Table.json +9 -0
- package/data/docs/types/TableBody.json +67 -0
- package/data/docs/types/TableBodyProps.json +9 -0
- package/data/docs/types/TableCaption.json +67 -0
- package/data/docs/types/TableCaptionProps.json +9 -0
- package/data/docs/types/TableCell.json +227 -0
- package/data/docs/types/TableCellProps.json +9 -0
- package/data/docs/types/TableColumn.json +101 -0
- package/data/docs/types/TableColumnGroup.json +101 -0
- package/data/docs/types/TableColumnGroupProps.json +9 -0
- package/data/docs/types/TableColumnHeader.json +193 -0
- package/data/docs/types/TableColumnHeaderProps.json +9 -0
- package/data/docs/types/TableColumnProps.json +9 -0
- package/data/docs/types/TableFooter.json +67 -0
- package/data/docs/types/TableFooterProps.json +9 -0
- package/data/docs/types/TableHeader.json +67 -0
- package/data/docs/types/TableHeaderProps.json +9 -0
- package/data/docs/types/TableRoot.json +365 -0
- package/data/docs/types/TableRootProps.json +12 -0
- package/data/docs/types/TableRow.json +67 -0
- package/data/docs/types/TableRowProps.json +9 -0
- package/data/docs/types/TableScrollArea.json +82 -0
- package/data/docs/types/TableScrollAreaProps.json +9 -0
- package/data/docs/types/Tabs.json +12 -0
- package/data/docs/types/TabsList.json +110 -0
- package/data/docs/types/TabsPanel.json +112 -0
- package/data/docs/types/TabsPanels.json +108 -0
- package/data/docs/types/TabsRoot.json +211 -0
- package/data/docs/types/TabsTab.json +174 -0
- package/data/docs/types/TagGroup.json +12 -0
- package/data/docs/types/TagGroupRoot.json +306 -0
- package/data/docs/types/TagGroupTag.json +595 -0
- package/data/docs/types/TagGroupTagList.json +166 -0
- package/data/docs/types/Text.json +119 -0
- package/data/docs/types/TextInput.json +1156 -0
- package/data/docs/types/TextInputField.json +1263 -0
- package/data/docs/types/TimeInput.json +752 -0
- package/data/docs/types/ToastAction.json +9 -0
- package/data/docs/types/ToastManagerApi.json +9 -0
- package/data/docs/types/ToastOptions.json +9 -0
- package/data/docs/types/ToastOutlet.json +12 -0
- package/data/docs/types/ToastPlacement.json +9 -0
- package/data/docs/types/ToastPromiseOptions.json +9 -0
- package/data/docs/types/ToastType.json +9 -0
- package/data/docs/types/ToastVariant.json +9 -0
- package/data/docs/types/ToggleButton.json +789 -0
- package/data/docs/types/ToggleButtonGroup.json +9 -0
- package/data/docs/types/ToggleButtonGroupButton.json +331 -0
- package/data/docs/types/ToggleButtonGroupRoot.json +269 -0
- package/data/docs/types/Toolbar.json +176 -0
- package/data/docs/types/Tooltip.json +12 -0
- package/data/docs/types/TooltipContent.json +372 -0
- package/data/docs/types/TooltipRoot.json +179 -0
- package/data/docs/types/Trigger.json +69 -0
- package/data/docs/types/VisuallyHidden.json +93 -0
- package/data/docs/types/__object.json +12 -0
- package/data/docs/types/filters.json +11 -0
- package/data/docs/types/manifest.json +278 -0
- package/data/docs/types/toast.json +234 -0
- package/data/docs/types/useColorMode.json +13 -0
- package/data/docs/types/useColorModeValue.json +13 -0
- package/data/docs/types/useColorScheme.json +12 -0
- package/data/docs/types/useLocalizedStringFormatter.json +14 -0
- package/data/icons.json +21940 -0
- package/data/tokens.json +40061 -0
- package/dist/index.js +2516 -17
- package/package.json +25 -6
- package/dist/data-loader.d.ts +0 -102
- package/dist/data-loader.js +0 -104
- package/dist/index.d.ts +0 -13
- package/dist/server.d.ts +0 -9
- package/dist/server.js +0 -22
- package/dist/server.spec.d.ts +0 -1
- package/dist/server.spec.js +0 -69
- package/dist/tools/list-components.d.ts +0 -9
- package/dist/tools/list-components.js +0 -42
- package/dist/types.d.ts +0 -28
- package/dist/types.js +0 -4
- package/src/data-loader.ts +0 -226
- package/src/index.ts +0 -29
- package/src/server.spec.ts +0 -86
- package/src/server.ts +0 -28
- package/src/tools/list-components.ts +0 -49
- package/src/types.ts +0 -31
- package/tsconfig.json +0 -14
- package/vitest.config.ts +0 -9
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"id": "Components-InlineSvg",
|
|
4
|
+
"title": "Inline svg",
|
|
5
|
+
"exportName": "InlineSvg",
|
|
6
|
+
"description": "The InlineSvg component allows you to render arbitrary SVG markup as an icon with built-in XSS protection. It sanitizes the provided SVG string to remove potentially dangerous elements and attributes before rendering.",
|
|
7
|
+
"lifecycleState": "Stable",
|
|
8
|
+
"order": 999,
|
|
9
|
+
"repoPath": "packages/nimbus/src/components/inline-svg/inline-svg.mdx",
|
|
10
|
+
"menu": [
|
|
11
|
+
"Components",
|
|
12
|
+
"Media",
|
|
13
|
+
"Inline svg"
|
|
14
|
+
],
|
|
15
|
+
"route": "components/media/inline-svg",
|
|
16
|
+
"tags": [
|
|
17
|
+
"component",
|
|
18
|
+
"svg",
|
|
19
|
+
"icon",
|
|
20
|
+
"inline",
|
|
21
|
+
"security"
|
|
22
|
+
],
|
|
23
|
+
"toc": [
|
|
24
|
+
{
|
|
25
|
+
"value": "Key features",
|
|
26
|
+
"href": "#key-features",
|
|
27
|
+
"depth": 2,
|
|
28
|
+
"numbering": [
|
|
29
|
+
1,
|
|
30
|
+
1
|
|
31
|
+
],
|
|
32
|
+
"parent": "root"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"value": "Basic usage",
|
|
36
|
+
"href": "#basic-usage",
|
|
37
|
+
"depth": 2,
|
|
38
|
+
"numbering": [
|
|
39
|
+
1,
|
|
40
|
+
2
|
|
41
|
+
],
|
|
42
|
+
"parent": "root"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"value": "Sizes",
|
|
46
|
+
"href": "#sizes",
|
|
47
|
+
"depth": 2,
|
|
48
|
+
"numbering": [
|
|
49
|
+
1,
|
|
50
|
+
3
|
|
51
|
+
],
|
|
52
|
+
"parent": "root"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"value": "Predefined sizes",
|
|
56
|
+
"href": "#predefined-sizes",
|
|
57
|
+
"depth": 3,
|
|
58
|
+
"numbering": [
|
|
59
|
+
1,
|
|
60
|
+
3,
|
|
61
|
+
1
|
|
62
|
+
],
|
|
63
|
+
"parent": "root"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"value": "Custom sizes",
|
|
67
|
+
"href": "#custom-sizes",
|
|
68
|
+
"depth": 3,
|
|
69
|
+
"numbering": [
|
|
70
|
+
1,
|
|
71
|
+
3,
|
|
72
|
+
2
|
|
73
|
+
],
|
|
74
|
+
"parent": "root"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"value": "Colors",
|
|
78
|
+
"href": "#colors",
|
|
79
|
+
"depth": 2,
|
|
80
|
+
"numbering": [
|
|
81
|
+
1,
|
|
82
|
+
4
|
|
83
|
+
],
|
|
84
|
+
"parent": "root"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"value": "Complex SVG",
|
|
88
|
+
"href": "#complex-svg",
|
|
89
|
+
"depth": 2,
|
|
90
|
+
"numbering": [
|
|
91
|
+
1,
|
|
92
|
+
5
|
|
93
|
+
],
|
|
94
|
+
"parent": "root"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"value": "Multi-Color SVG",
|
|
98
|
+
"href": "#multi-color-svg",
|
|
99
|
+
"depth": 2,
|
|
100
|
+
"numbering": [
|
|
101
|
+
1,
|
|
102
|
+
6
|
|
103
|
+
],
|
|
104
|
+
"parent": "root"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"value": "Security",
|
|
108
|
+
"href": "#security",
|
|
109
|
+
"depth": 2,
|
|
110
|
+
"numbering": [
|
|
111
|
+
1,
|
|
112
|
+
7
|
|
113
|
+
],
|
|
114
|
+
"parent": "root"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"value": "Best practices",
|
|
118
|
+
"href": "#best-practices",
|
|
119
|
+
"depth": 2,
|
|
120
|
+
"numbering": [
|
|
121
|
+
1,
|
|
122
|
+
8
|
|
123
|
+
],
|
|
124
|
+
"parent": "root"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"layout": "app-frame",
|
|
128
|
+
"tabs": [
|
|
129
|
+
{
|
|
130
|
+
"key": "overview",
|
|
131
|
+
"title": "Overview",
|
|
132
|
+
"order": 0
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"key": "dev",
|
|
136
|
+
"title": "Implementation",
|
|
137
|
+
"order": 3
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"key": "a11y",
|
|
141
|
+
"title": "Accessibility",
|
|
142
|
+
"order": 4
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"mdx": "\n## Key features\n\n- **Security First**: Automatic sanitization of SVG content to prevent XSS\n attacks\n- **API Compatible**: Drop-in replacement for existing InlineSvg implementations\n- **Accessibility**: Support for title and description elements\n- **Consistent Styling**: Uses the same recipe system as the Icon component\n- **Performance**: Memoized sanitization for optimal re-renders\n- **Zero External Dependencies**: Uses native browser APIs for parsing and\n sanitization\n\n## Basic usage\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"md\" />\n );\n};\n```\n\n## Sizes\n\n### Predefined sizes\n\nThe component supports all standard icon sizes through the `size` prop:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} size=\"2xs\" />\n <InlineSvg data={svgData} size=\"xs\" />\n <InlineSvg data={svgData} size=\"sm\" />\n <InlineSvg data={svgData} size=\"md\" />\n <InlineSvg data={svgData} size=\"lg\" />\n <InlineSvg data={svgData} size=\"xl\" />\n </Flex>\n );\n};\n```\n\n### Custom sizes\n\nFor custom sizing, you can use the `boxSize`, `width`, or `height` props with\nany valid CSS value or design token:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} boxSize=\"800\"/>\n <InlineSvg data={svgData} boxSize=\"1600\"/>\n <InlineSvg data={svgData} width=\"800\" height=\"800\"/>\n </Flex>\n );\n};\n```\n\n## Colors\n\nApply colors using design tokens:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} size=\"lg\" color=\"primary.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"neutral.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"info.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"positive.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"warning.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"critical.9\" />\n </Flex>\n );\n};\n```\n\n## Complex SVG\n\nThe component preserves complex SVG structures including groups, multiple paths,\nand transformations:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg fill=\"none\" height=\"24\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <polyline points=\"7.5 19.79 7.5 14.6 3 12\"/>\n <polyline points=\"21 12 16.5 14.6 16.5 19.79\"/>\n <polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n</svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"xl\" color=\"primary.9\" />\n );\n};\n```\n\n## Multi-Color SVG\n\nSVGs with inline colors are preserved:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" fill=\"#e11d48\"/>\n <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"#10b981\"/>\n <path d=\"M12 9v6M9 12h6\" stroke=\"white\" stroke-width=\"2\"/>\n</svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"xl\" />\n );\n};\n```\n\n## Security\n\nThe component automatically sanitizes potentially dangerous content:\n\n- Removes `<script>` tags\n- Removes event handlers (onclick, onload, etc.)\n- Removes `<style>` tags\n- Sanitizes URLs in href attributes (blocks javascript:, data:, etc.)\n- Removes other potentially dangerous elements\n\n```jsx live\nconst App = () => {\n // This malicious SVG content will be sanitized\n const maliciousSvg = `<svg fill=\"none\" height=\"24\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\" onclick=\"alert('XSS')\" onLoad=\"alert('XSS2')\">\n <path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" onmouseover=\"alert('XSS4')\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <polyline points=\"7.5 19.79 7.5 14.6 3 12\"/>\n <polyline points=\"21 12 16.5 14.6 16.5 19.79\"/>\n <polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n <style>body { display: none; }</style>\n <script>alert('XSS3')</script>\n</svg>`;\n\n return (\n <Stack gap=\"400\">\n <Text>The following SVG has malicious content that gets sanitized:</Text>\n <InlineSvg data={maliciousSvg} size=\"lg\" />\n <Text fontSize=\"sm\" color=\"neutral.9\">\n Script tags, event handlers, and style tags are automatically removed\n </Text>\n </Stack>\n );\n};\n```\n\n## Best practices\n\n1. **Always provide a title** for non-decorative SVGs\n2. **Use design tokens** for colors to maintain consistency\n3. **Test with real SVG data** from your actual use cases\n4. **Validate SVG markup** before storing in your database\n5. **Consider performance** for very large or complex SVGs\n",
|
|
147
|
+
"views": {
|
|
148
|
+
"overview": {
|
|
149
|
+
"mdx": "\n## Key features\n\n- **Security First**: Automatic sanitization of SVG content to prevent XSS\n attacks\n- **API Compatible**: Drop-in replacement for existing InlineSvg implementations\n- **Accessibility**: Support for title and description elements\n- **Consistent Styling**: Uses the same recipe system as the Icon component\n- **Performance**: Memoized sanitization for optimal re-renders\n- **Zero External Dependencies**: Uses native browser APIs for parsing and\n sanitization\n\n## Basic usage\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"md\" />\n );\n};\n```\n\n## Sizes\n\n### Predefined sizes\n\nThe component supports all standard icon sizes through the `size` prop:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} size=\"2xs\" />\n <InlineSvg data={svgData} size=\"xs\" />\n <InlineSvg data={svgData} size=\"sm\" />\n <InlineSvg data={svgData} size=\"md\" />\n <InlineSvg data={svgData} size=\"lg\" />\n <InlineSvg data={svgData} size=\"xl\" />\n </Flex>\n );\n};\n```\n\n### Custom sizes\n\nFor custom sizing, you can use the `boxSize`, `width`, or `height` props with\nany valid CSS value or design token:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} boxSize=\"800\"/>\n <InlineSvg data={svgData} boxSize=\"1600\"/>\n <InlineSvg data={svgData} width=\"800\" height=\"800\"/>\n </Flex>\n );\n};\n```\n\n## Colors\n\nApply colors using design tokens:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5\n 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0\n 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n\n return (\n <Flex gap=\"400\" align=\"center\">\n <InlineSvg data={svgData} size=\"lg\" color=\"primary.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"neutral.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"info.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"positive.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"warning.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"critical.9\" />\n </Flex>\n );\n};\n```\n\n## Complex SVG\n\nThe component preserves complex SVG structures including groups, multiple paths,\nand transformations:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg fill=\"none\" height=\"24\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <polyline points=\"7.5 19.79 7.5 14.6 3 12\"/>\n <polyline points=\"21 12 16.5 14.6 16.5 19.79\"/>\n <polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n</svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"xl\" color=\"primary.9\" />\n );\n};\n```\n\n## Multi-Color SVG\n\nSVGs with inline colors are preserved:\n\n```jsx live\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" fill=\"#e11d48\"/>\n <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"#10b981\"/>\n <path d=\"M12 9v6M9 12h6\" stroke=\"white\" stroke-width=\"2\"/>\n</svg>`;\n\n return (\n <InlineSvg data={svgData} size=\"xl\" />\n );\n};\n```\n\n## Security\n\nThe component automatically sanitizes potentially dangerous content:\n\n- Removes `<script>` tags\n- Removes event handlers (onclick, onload, etc.)\n- Removes `<style>` tags\n- Sanitizes URLs in href attributes (blocks javascript:, data:, etc.)\n- Removes other potentially dangerous elements\n\n```jsx live\nconst App = () => {\n // This malicious SVG content will be sanitized\n const maliciousSvg = `<svg fill=\"none\" height=\"24\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\" onclick=\"alert('XSS')\" onLoad=\"alert('XSS2')\">\n <path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" onmouseover=\"alert('XSS4')\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <polyline points=\"7.5 19.79 7.5 14.6 3 12\"/>\n <polyline points=\"21 12 16.5 14.6 16.5 19.79\"/>\n <polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n <style>body { display: none; }</style>\n <script>alert('XSS3')</script>\n</svg>`;\n\n return (\n <Stack gap=\"400\">\n <Text>The following SVG has malicious content that gets sanitized:</Text>\n <InlineSvg data={maliciousSvg} size=\"lg\" />\n <Text fontSize=\"sm\" color=\"neutral.9\">\n Script tags, event handlers, and style tags are automatically removed\n </Text>\n </Stack>\n );\n};\n```\n\n## Best practices\n\n1. **Always provide a title** for non-decorative SVGs\n2. **Use design tokens** for colors to maintain consistency\n3. **Test with real SVG data** from your actual use cases\n4. **Validate SVG markup** before storing in your database\n5. **Consider performance** for very large or complex SVGs\n",
|
|
150
|
+
"toc": [
|
|
151
|
+
{
|
|
152
|
+
"value": "Key features",
|
|
153
|
+
"href": "#key-features",
|
|
154
|
+
"depth": 2,
|
|
155
|
+
"numbering": [
|
|
156
|
+
1,
|
|
157
|
+
1
|
|
158
|
+
],
|
|
159
|
+
"parent": "root"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"value": "Basic usage",
|
|
163
|
+
"href": "#basic-usage",
|
|
164
|
+
"depth": 2,
|
|
165
|
+
"numbering": [
|
|
166
|
+
1,
|
|
167
|
+
2
|
|
168
|
+
],
|
|
169
|
+
"parent": "root"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"value": "Sizes",
|
|
173
|
+
"href": "#sizes",
|
|
174
|
+
"depth": 2,
|
|
175
|
+
"numbering": [
|
|
176
|
+
1,
|
|
177
|
+
3
|
|
178
|
+
],
|
|
179
|
+
"parent": "root"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"value": "Predefined sizes",
|
|
183
|
+
"href": "#predefined-sizes",
|
|
184
|
+
"depth": 3,
|
|
185
|
+
"numbering": [
|
|
186
|
+
1,
|
|
187
|
+
3,
|
|
188
|
+
1
|
|
189
|
+
],
|
|
190
|
+
"parent": "root"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"value": "Custom sizes",
|
|
194
|
+
"href": "#custom-sizes",
|
|
195
|
+
"depth": 3,
|
|
196
|
+
"numbering": [
|
|
197
|
+
1,
|
|
198
|
+
3,
|
|
199
|
+
2
|
|
200
|
+
],
|
|
201
|
+
"parent": "root"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"value": "Colors",
|
|
205
|
+
"href": "#colors",
|
|
206
|
+
"depth": 2,
|
|
207
|
+
"numbering": [
|
|
208
|
+
1,
|
|
209
|
+
4
|
|
210
|
+
],
|
|
211
|
+
"parent": "root"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"value": "Complex SVG",
|
|
215
|
+
"href": "#complex-svg",
|
|
216
|
+
"depth": 2,
|
|
217
|
+
"numbering": [
|
|
218
|
+
1,
|
|
219
|
+
5
|
|
220
|
+
],
|
|
221
|
+
"parent": "root"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"value": "Multi-Color SVG",
|
|
225
|
+
"href": "#multi-color-svg",
|
|
226
|
+
"depth": 2,
|
|
227
|
+
"numbering": [
|
|
228
|
+
1,
|
|
229
|
+
6
|
|
230
|
+
],
|
|
231
|
+
"parent": "root"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"value": "Security",
|
|
235
|
+
"href": "#security",
|
|
236
|
+
"depth": 2,
|
|
237
|
+
"numbering": [
|
|
238
|
+
1,
|
|
239
|
+
7
|
|
240
|
+
],
|
|
241
|
+
"parent": "root"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"value": "Best practices",
|
|
245
|
+
"href": "#best-practices",
|
|
246
|
+
"depth": 2,
|
|
247
|
+
"numbering": [
|
|
248
|
+
1,
|
|
249
|
+
8
|
|
250
|
+
],
|
|
251
|
+
"parent": "root"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
"a11y": {
|
|
256
|
+
"mdx": "\n## Accessibility\n\nAccessibility ensures that digital content and functionality are usable by\neveryone, including people with disabilities, by addressing visual, auditory,\ncognitive, and physical limitations.\n\n```jsx live\nconst App = () => (\n <InlineSvg\n svgContent='<svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\" /></svg>'\n />\n);\n```\n\n### Accessibility standards\n\n- **Decorative SVGs:** The SVG is rendered with `role=\"presentation\"` by default\n as it's intended for decorative use. This hides the SVG from screen readers.\n- **Accessible SVGs:** If you need accessible SVGs, include `<title>` and\n `<desc>` elements directly in your SVG markup - they will be preserved during\n sanitization.\n- **Avoid conveying meaning through decorative images:** Don't rely on\n decorative SVGs to communicate important information.\n- **Provide text alternatives:** Ensure important information is available\n through text content, not just visual elements.\n\n## Resources\n\n- [W3C SVG Accessibility](https://www.w3.org/WAI/tutorials/images/)\n",
|
|
257
|
+
"toc": [
|
|
258
|
+
{
|
|
259
|
+
"value": "Accessibility",
|
|
260
|
+
"href": "#accessibility",
|
|
261
|
+
"depth": 2,
|
|
262
|
+
"numbering": [
|
|
263
|
+
1,
|
|
264
|
+
1
|
|
265
|
+
],
|
|
266
|
+
"parent": "root"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"value": "Accessibility standards",
|
|
270
|
+
"href": "#accessibility-standards",
|
|
271
|
+
"depth": 3,
|
|
272
|
+
"numbering": [
|
|
273
|
+
1,
|
|
274
|
+
1,
|
|
275
|
+
1
|
|
276
|
+
],
|
|
277
|
+
"parent": "root"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"value": "Resources",
|
|
281
|
+
"href": "#resources",
|
|
282
|
+
"depth": 2,
|
|
283
|
+
"numbering": [
|
|
284
|
+
1,
|
|
285
|
+
2
|
|
286
|
+
],
|
|
287
|
+
"parent": "root"
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
},
|
|
291
|
+
"dev": {
|
|
292
|
+
"mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { InlineSvg, type InlineSvgProps } from \"@commercetools/nimbus\";\n```\n\n### Basic usage\n\n```jsx live-dev\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`;\n \n return <InlineSvg data={svgData} size=\"md\" />;\n};\n```\n\n## Usage examples\n\n### Size variants\n\nInlineSvg supports the same size variants as the Icon component.\n\n```jsx live-dev\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n \n return (\n <Stack gap=\"400\" direction=\"row\" align=\"center\">\n <InlineSvg data={svgData} size=\"2xs\" />\n <InlineSvg data={svgData} size=\"xs\" />\n <InlineSvg data={svgData} size=\"sm\" />\n <InlineSvg data={svgData} size=\"md\" />\n <InlineSvg data={svgData} size=\"lg\" />\n <InlineSvg data={svgData} size=\"xl\" />\n </Stack>\n );\n};\n```\n\n### Color customization\n\nUse the `color` prop to control the icon color. The SVG should use `currentColor` to inherit the color.\n\n```jsx live-dev\nconst App = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5zm0 2.18l8 3.6v8.72c0 4.55-3.12 8.86-8 10.19-4.88-1.33-8-5.64-8-10.19V7.78l8-3.6z\" fill=\"currentColor\"/>\n </svg>`;\n \n return (\n <Stack gap=\"400\" direction=\"row\">\n <InlineSvg data={svgData} size=\"lg\" color=\"primary.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"info.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"positive.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"warning.9\" />\n <InlineSvg data={svgData} size=\"lg\" color=\"critical.9\" />\n </Stack>\n );\n};\n```\n\n### Multi-color SVGs\n\nInlineSvg preserves inline colors defined in the SVG markup. Use this for icons with multiple colors that shouldn't inherit `currentColor`.\n\n```jsx live-dev\nconst App = () => {\n const multiColorSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" fill=\"#e11d48\"/>\n <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"#10b981\"/>\n <path d=\"M12 9v6M9 12h6\" stroke=\"white\" stroke-width=\"2\"/>\n </svg>`;\n \n return (\n <Stack gap=\"400\">\n <Box>\n <Text mb=\"200\" fontWeight=\"semibold\">Multi-color SVG</Text>\n <InlineSvg data={multiColorSvg} size=\"xl\" />\n </Box>\n \n <Text fontSize=\"sm\" color=\"neutral.3\">\n Colors defined in the SVG are preserved regardless of the color prop\n </Text>\n </Stack>\n );\n};\n```\n\n### Complex SVG structures\n\nInlineSvg handles complex SVG markup with multiple paths, groups, and attributes.\n\n```jsx live-dev\nconst App = () => {\n const complexSvg = `<svg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <polyline points=\"7.5 19.79 7.5 14.6 3 12\"/>\n <polyline points=\"21 12 16.5 14.6 16.5 19.79\"/>\n <polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n </svg>`;\n \n return <InlineSvg data={complexSvg} size=\"xl\" color=\"primary.9\" />;\n};\n```\n\n### Dynamic SVG content\n\nInlineSvg is useful when working with SVG strings from APIs or databases.\n\n```jsx live-dev\nconst App = () => {\n const [selectedIcon, setSelectedIcon] = React.useState('heart');\n \n const icons = {\n heart: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" fill=\"currentColor\"/>\n </svg>`,\n star: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\" fill=\"currentColor\"/>\n </svg>`,\n check: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" fill=\"currentColor\"/>\n </svg>`\n };\n \n return (\n <Stack gap=\"400\">\n <Stack gap=\"200\" direction=\"row\">\n <Button\n size=\"sm\"\n variant={selectedIcon === 'heart' ? 'solid' : 'outline'}\n onClick={() => setSelectedIcon('heart')}\n >\n Heart\n </Button>\n <Button\n size=\"sm\"\n variant={selectedIcon === 'star' ? 'solid' : 'outline'}\n onClick={() => setSelectedIcon('star')}\n >\n Star\n </Button>\n <Button\n size=\"sm\"\n variant={selectedIcon === 'check' ? 'solid' : 'outline'}\n onClick={() => setSelectedIcon('check')}\n >\n Check\n </Button>\n </Stack>\n \n <Box \n p=\"600\" \n bg=\"neutral.7\" \n borderRadius=\"md\"\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <InlineSvg \n data={icons[selectedIcon]} \n size=\"xl\" \n color=\"primary.9\" \n />\n </Box>\n </Stack>\n );\n};\n```\n\n## Component requirements\n\n### Usage context\n\n**When to use InlineSvg**:\n- Rendering SVG markup from strings (API responses, databases, CMS)\n- Dynamic SVG content that needs sanitization\n- When you need XSS protection for user-generated SVG content\n- SVG icons that aren't available in the nimbus-icons library\n\n**When NOT to use**:\n- For static icons - use the `Icon` component with `@commercetools/nimbus-icons` instead\n- For images - use the `Image` component\n- When you need `asChild` composition - InlineSvg always renders as an SVG element\n\n### Security\n\n**XSS Protection**: InlineSvg automatically sanitizes SVG content to remove:\n- `<script>` tags and event handlers (`onclick`, `onload`, etc.)\n- `<style>` tags (to prevent CSS injection)\n- Dangerous attributes like `xlink:href` with malicious payloads\n- Other potentially harmful SVG features\n\n**Safe SVG Requirements**:\n- SVG must be valid XML\n- Use `fill=\"currentColor\"` or `stroke=\"currentColor\"` for color inheritance\n- Avoid external resources (external stylesheets, fonts)\n- Test SVG content from untrusted sources\n\n```jsx live-dev\nconst App = () => {\n // This malicious SVG will be sanitized - script tags and event handlers removed\n const maliciousSvg = `<svg viewBox=\"0 0 24 24\" onclick=\"alert('XSS')\" xmlns=\"http://www.w3.org/2000/svg\">\n <script>alert('malicious')</script>\n <path d=\"M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z\" fill=\"currentColor\"/>\n </svg>`;\n \n return (\n <Stack gap=\"400\">\n <InlineSvg data={maliciousSvg} size=\"lg\" color=\"positive.9\" />\n <Text fontSize=\"sm\" color=\"neutral.3\">\n The SVG renders safely - malicious content has been removed\n </Text>\n </Stack>\n );\n};\n```\n\n## Accessibility\n\n**Role**: InlineSvg renders with `role=\"presentation\"` by default, treating the SVG as decorative.\n\n**Labeling**: For meaningful icons, provide accessible labels using surrounding context or ARIA attributes:\n\n```tsx\n<Button>\n <InlineSvg data={saveSvg} size=\"sm\" />\n Save Document\n</Button>\n```\n\n**Standalone icons**: If the InlineSvg is the only content, ensure proper labeling:\n\n```tsx\n<button aria-label=\"Save document\">\n <InlineSvg data={saveSvg} size=\"md\" />\n</button>\n```\n\n### Persistent ID\n\nIf your use case requires tracking and analytics for this component, it is good practice to add a **persistent**, **unique** id to the component:\n\n```tsx\nconst PERSISTENT_ID = \"feature-icon\";\n\nexport const FeatureIcon = () => {\n const svgData = `<svg viewBox=\"0 0 24 24\">...</svg>`;\n \n return (\n <InlineSvg \n id={PERSISTENT_ID} \n data={svgData} \n size=\"lg\" \n color=\"primary.9\" \n />\n );\n};\n```\n\n## API reference\n\n<PropsTable id=\"InlineSvg\" />\n\n## Common patterns\n\n### Loading SVG from API\n\nHandle loading states and errors when fetching SVG data from an API.\n\n```jsx live-dev\nconst App = () => {\n const [svgData, setSvgData] = React.useState<string | null>(null);\n const [isLoading, setIsLoading] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n \n const loadSvg = () => {\n setIsLoading(true);\n setError(null);\n \n // Simulate API call\n setTimeout(() => {\n const mockSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" fill=\"currentColor\"/>\n </svg>`;\n setSvgData(mockSvg);\n setIsLoading(false);\n }, 1000);\n };\n \n return (\n <Stack gap=\"400\">\n <Button onClick={loadSvg} isDisabled={isLoading}>\n {isLoading ? 'Loading...' : 'Load Icon from API'}\n </Button>\n \n {svgData && (\n <Box \n p=\"400\" \n bg=\"positive.7\" \n borderRadius=\"md\"\n display=\"flex\"\n alignItems=\"center\"\n gap=\"300\"\n >\n <InlineSvg data={svgData} size=\"lg\" color=\"positive.9\" />\n <Text>Icon loaded successfully!</Text>\n </Box>\n )}\n \n {error && (\n <Box p=\"400\" bg=\"critical.7\" borderRadius=\"md\">\n <Text color=\"critical.9\">{error}</Text>\n </Box>\n )}\n </Stack>\n );\n};\n```\n\n### Fallback for invalid SVG\n\nHandle cases where SVG data might be invalid or fail sanitization.\n\n```jsx live-dev\nconst App = () => {\n const [svgInput, setSvgInput] = React.useState('');\n const [displaySvg, setDisplaySvg] = React.useState<string | null>(null);\n \n const validSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n \n const invalidSvg = 'This is not valid SVG markup';\n \n return (\n <Stack gap=\"400\">\n <Stack gap=\"200\" direction=\"row\">\n <Button size=\"sm\" onClick={() => setDisplaySvg(validSvg)}>\n Show Valid SVG\n </Button>\n <Button size=\"sm\" onClick={() => setDisplaySvg(invalidSvg)}>\n Show Invalid SVG\n </Button>\n <Button size=\"sm\" onClick={() => setDisplaySvg(null)}>\n Clear\n </Button>\n </Stack>\n \n {displaySvg && (\n <Box p=\"400\" bg=\"neutral.7\" borderRadius=\"md\">\n {displaySvg.includes('<svg') ? (\n <Stack gap=\"200\" direction=\"row\" align=\"center\">\n <InlineSvg data={displaySvg} size=\"lg\" color=\"positive.9\" />\n <Text>Valid SVG rendered</Text>\n </Stack>\n ) : (\n <Stack gap=\"200\" direction=\"row\" align=\"center\">\n <Icon name=\"error\" size=\"lg\" color=\"critical.9\" />\n <Text>Invalid SVG - showing fallback icon</Text>\n </Stack>\n )}\n </Box>\n )}\n </Stack>\n );\n};\n```\n\n### Icon library from database\n\nManage a collection of SVG icons stored as strings.\n\n```jsx live-dev\nconst App = () => {\n // Simulated icon library from database\n const iconLibrary = [\n {\n id: 'dashboard',\n name: 'Dashboard',\n svg: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z\" fill=\"currentColor\"/>\n </svg>`\n },\n {\n id: 'settings',\n name: 'Settings',\n svg: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\" fill=\"currentColor\"/>\n </svg>`\n },\n {\n id: 'profile',\n name: 'Profile',\n svg: `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" fill=\"currentColor\"/>\n </svg>`\n }\n ];\n \n return (\n <Stack gap=\"400\">\n <Text fontWeight=\"semibold\">Icon Library</Text>\n <Stack gap=\"300\">\n {iconLibrary.map((icon) => (\n <Box \n key={icon.id}\n p=\"300\" \n bg=\"neutral.7\" \n borderRadius=\"md\"\n display=\"flex\"\n alignItems=\"center\"\n gap=\"300\"\n >\n <InlineSvg data={icon.svg} size=\"md\" color=\"primary.9\" />\n <Text>{icon.name}</Text>\n </Box>\n ))}\n </Stack>\n </Stack>\n );\n};\n```\n\n### Custom icon button\n\nCreate icon buttons using SVG strings.\n\n```jsx live-dev\nconst App = () => {\n const [count, setCount] = React.useState(0);\n \n const plusSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" fill=\"currentColor\"/>\n </svg>`;\n \n const minusSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 13H5v-2h14v2z\" fill=\"currentColor\"/>\n </svg>`;\n \n return (\n <Stack gap=\"400\">\n <Stack gap=\"300\" direction=\"row\" align=\"center\">\n <Button\n size=\"sm\"\n onClick={() => setCount(count - 1)}\n isDisabled={count <= 0}\n >\n <InlineSvg data={minusSvg} size=\"sm\" />\n </Button>\n \n <Box \n minW=\"60px\" \n textAlign=\"center\" \n p=\"200\" \n bg=\"neutral.7\" \n borderRadius=\"md\"\n >\n <Text fontWeight=\"bold\">{count}</Text>\n </Box>\n \n <Button\n size=\"sm\"\n onClick={() => setCount(count + 1)}\n >\n <InlineSvg data={plusSvg} size=\"sm\" />\n </Button>\n </Stack>\n </Stack>\n );\n};\n```\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using InlineSvg within your application. As the component's internal functionality is already tested by Nimbus, these patterns help you verify your integration and application-specific logic.\n\n### Basic Usage Tests\n\nVerify InlineSvg renders SVG content correctly from string data\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { InlineSvg, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"InlineSvg - Basic usage\", () => {\n it(\"renders valid SVG content from string\", () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg).toBeInTheDocument();\n expect(svg.tagName).toBe(\"svg\");\n expect(svg).toHaveAttribute(\"viewBox\", \"0 0 24 24\");\n expect(svg.querySelector(\"circle\")).toBeInTheDocument();\n });\n\n it(\"preserves SVG attributes from the source\", () => {\n const svgData = `<svg fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 2L2 7v10l10 5 10-5V7z\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg).toHaveAttribute(\"viewBox\", \"0 0 24 24\");\n expect(svg).toHaveAttribute(\"stroke\", \"currentColor\");\n expect(svg.querySelector(\"path\")).toBeInTheDocument();\n });\n\n it(\"handles invalid SVG gracefully\", () => {\n // Suppress expected warning when invalid SVG is passed\n const consoleSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n const invalidSvg = \"This is not valid SVG markup\";\n\n render(\n <NimbusProvider>\n <InlineSvg data={invalidSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n // Component should not render when SVG is invalid\n expect(screen.queryByTestId(\"inline-svg\")).not.toBeInTheDocument();\n\n // Verify the warning was called and restore\n expect(consoleSpy).toHaveBeenCalledWith(\n \"InlineSvg: No SVG element found in markup\"\n );\n consoleSpy.mockRestore();\n });\n});\n```\n\n### Security Tests\n\nVerify SVG sanitization removes malicious content\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { InlineSvg, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"InlineSvg - Security\", () => {\n it(\"removes script tags from SVG\", () => {\n const maliciousSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <script>alert('XSS')</script>\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={maliciousSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg.querySelector(\"script\")).not.toBeInTheDocument();\n });\n\n it(\"removes event handlers from SVG elements\", () => {\n const maliciousSvg = `<svg viewBox=\"0 0 24 24\" onclick=\"alert('XSS')\" xmlns=\"http://www.w3.org/2000/svg\">\n <path onclick=\"alert('XSS2')\" d=\"M12 2L2 7v10l10 5 10-5V7z\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={maliciousSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg).not.toHaveAttribute(\"onclick\");\n\n const path = svg.querySelector(\"path\");\n expect(path).not.toHaveAttribute(\"onclick\");\n });\n\n it(\"removes style tags from SVG\", () => {\n const maliciousSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <style>body { display: none; }</style>\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={maliciousSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg.querySelector(\"style\")).not.toBeInTheDocument();\n });\n});\n```\n\n### Styling Tests\n\nVerify size variants and color customization\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { InlineSvg, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"InlineSvg - Styling\", () => {\n it(\"applies size variants\", () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n const { rerender } = render(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"sm\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n expect(screen.getByTestId(\"inline-svg\")).toBeInTheDocument();\n\n rerender(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"lg\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n expect(screen.getByTestId(\"inline-svg\")).toBeInTheDocument();\n });\n\n it(\"preserves multi-color SVG attributes\", () => {\n const multiColorSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"0\" y=\"0\" width=\"24\" height=\"24\" fill=\"#e11d48\"/>\n <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"#10b981\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={multiColorSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n const rect = svg.querySelector(\"rect\");\n const circle = svg.querySelector(\"circle\");\n\n expect(rect).toHaveAttribute(\"fill\", \"#e11d48\");\n expect(circle).toHaveAttribute(\"fill\", \"#10b981\");\n });\n\n it(\"always renders as svg element\", () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const element = screen.getByTestId(\"inline-svg\");\n expect(element.tagName.toLowerCase()).toBe(\"svg\");\n });\n});\n```\n\n### Accessibility Tests\n\nVerify accessibility attributes and presentation role\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { InlineSvg, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"InlineSvg - Accessibility\", () => {\n it(\"renders with presentation role\", () => {\n const svgData = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"currentColor\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={svgData} size=\"md\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByRole(\"presentation\");\n expect(svg).toBeInTheDocument();\n });\n});\n```\n\n### Complex SVG Tests\n\nVerify handling of complex SVG structures\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { InlineSvg, NimbusProvider } from \"@commercetools/nimbus\";\n\ndescribe(\"InlineSvg - Complex SVG\", () => {\n it(\"handles SVG with multiple paths and elements\", () => {\n const complexSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 2L2 7v10l10 5 10-5V7z\"/>\n <polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"/>\n <line x1=\"12\" x2=\"12\" y1=\"22.08\" y2=\"12\"/>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={complexSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n expect(svg.querySelector(\"path\")).toBeInTheDocument();\n expect(svg.querySelector(\"polyline\")).toBeInTheDocument();\n expect(svg.querySelector(\"line\")).toBeInTheDocument();\n });\n\n it(\"preserves nested SVG groups\", () => {\n const groupedSvg = `<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <g fill=\"currentColor\">\n <circle cx=\"8\" cy=\"12\" r=\"3\"/>\n <circle cx=\"16\" cy=\"12\" r=\"3\"/>\n </g>\n </svg>`;\n\n render(\n <NimbusProvider>\n <InlineSvg data={groupedSvg} size=\"md\" data-testid=\"inline-svg\" />\n </NimbusProvider>\n );\n\n const svg = screen.getByTestId(\"inline-svg\");\n const group = svg.querySelector(\"g\");\n expect(group).toBeInTheDocument();\n expect(group?.querySelectorAll(\"circle\")).toHaveLength(2);\n });\n});\n```\n\n\n## Resources\n\n- [InlineSvg component in Storybook](https://nimbus-storybook.vercel.app/?path=/docs/components-inlinesvg--docs)\n- [Icon component](/components/media/icon) - For static icons from the nimbus-icons library\n- [SVG on MDN](https://developer.mozilla.org/en-US/docs/Web/SVG)\n- [Content Security Policy for SVG](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)\n",
|
|
293
|
+
"toc": [
|
|
294
|
+
{
|
|
295
|
+
"value": "Getting started",
|
|
296
|
+
"href": "#getting-started",
|
|
297
|
+
"depth": 2,
|
|
298
|
+
"numbering": [
|
|
299
|
+
1,
|
|
300
|
+
1
|
|
301
|
+
],
|
|
302
|
+
"parent": "root"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"value": "Import",
|
|
306
|
+
"href": "#import",
|
|
307
|
+
"depth": 3,
|
|
308
|
+
"numbering": [
|
|
309
|
+
1,
|
|
310
|
+
1,
|
|
311
|
+
1
|
|
312
|
+
],
|
|
313
|
+
"parent": "root"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"value": "Basic usage",
|
|
317
|
+
"href": "#basic-usage",
|
|
318
|
+
"depth": 3,
|
|
319
|
+
"numbering": [
|
|
320
|
+
1,
|
|
321
|
+
1,
|
|
322
|
+
2
|
|
323
|
+
],
|
|
324
|
+
"parent": "root"
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"value": "Usage examples",
|
|
328
|
+
"href": "#usage-examples",
|
|
329
|
+
"depth": 2,
|
|
330
|
+
"numbering": [
|
|
331
|
+
1,
|
|
332
|
+
2
|
|
333
|
+
],
|
|
334
|
+
"parent": "root"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"value": "Size variants",
|
|
338
|
+
"href": "#size-variants",
|
|
339
|
+
"depth": 3,
|
|
340
|
+
"numbering": [
|
|
341
|
+
1,
|
|
342
|
+
2,
|
|
343
|
+
1
|
|
344
|
+
],
|
|
345
|
+
"parent": "root"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"value": "Color customization",
|
|
349
|
+
"href": "#color-customization",
|
|
350
|
+
"depth": 3,
|
|
351
|
+
"numbering": [
|
|
352
|
+
1,
|
|
353
|
+
2,
|
|
354
|
+
2
|
|
355
|
+
],
|
|
356
|
+
"parent": "root"
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"value": "Multi-color SVGs",
|
|
360
|
+
"href": "#multi-color-svgs",
|
|
361
|
+
"depth": 3,
|
|
362
|
+
"numbering": [
|
|
363
|
+
1,
|
|
364
|
+
2,
|
|
365
|
+
3
|
|
366
|
+
],
|
|
367
|
+
"parent": "root"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"value": "Complex SVG structures",
|
|
371
|
+
"href": "#complex-svg-structures",
|
|
372
|
+
"depth": 3,
|
|
373
|
+
"numbering": [
|
|
374
|
+
1,
|
|
375
|
+
2,
|
|
376
|
+
4
|
|
377
|
+
],
|
|
378
|
+
"parent": "root"
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"value": "Dynamic SVG content",
|
|
382
|
+
"href": "#dynamic-svg-content",
|
|
383
|
+
"depth": 3,
|
|
384
|
+
"numbering": [
|
|
385
|
+
1,
|
|
386
|
+
2,
|
|
387
|
+
5
|
|
388
|
+
],
|
|
389
|
+
"parent": "root"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"value": "Component requirements",
|
|
393
|
+
"href": "#component-requirements",
|
|
394
|
+
"depth": 2,
|
|
395
|
+
"numbering": [
|
|
396
|
+
1,
|
|
397
|
+
3
|
|
398
|
+
],
|
|
399
|
+
"parent": "root"
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"value": "Usage context",
|
|
403
|
+
"href": "#usage-context",
|
|
404
|
+
"depth": 3,
|
|
405
|
+
"numbering": [
|
|
406
|
+
1,
|
|
407
|
+
3,
|
|
408
|
+
1
|
|
409
|
+
],
|
|
410
|
+
"parent": "root"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"value": "Security",
|
|
414
|
+
"href": "#security",
|
|
415
|
+
"depth": 3,
|
|
416
|
+
"numbering": [
|
|
417
|
+
1,
|
|
418
|
+
3,
|
|
419
|
+
2
|
|
420
|
+
],
|
|
421
|
+
"parent": "root"
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
"value": "Accessibility",
|
|
425
|
+
"href": "#accessibility",
|
|
426
|
+
"depth": 2,
|
|
427
|
+
"numbering": [
|
|
428
|
+
1,
|
|
429
|
+
4
|
|
430
|
+
],
|
|
431
|
+
"parent": "root"
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"value": "Persistent ID",
|
|
435
|
+
"href": "#persistent-id",
|
|
436
|
+
"depth": 3,
|
|
437
|
+
"numbering": [
|
|
438
|
+
1,
|
|
439
|
+
4,
|
|
440
|
+
1
|
|
441
|
+
],
|
|
442
|
+
"parent": "root"
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"value": "API reference",
|
|
446
|
+
"href": "#api-reference",
|
|
447
|
+
"depth": 2,
|
|
448
|
+
"numbering": [
|
|
449
|
+
1,
|
|
450
|
+
5
|
|
451
|
+
],
|
|
452
|
+
"parent": "root"
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"value": "Common patterns",
|
|
456
|
+
"href": "#common-patterns",
|
|
457
|
+
"depth": 2,
|
|
458
|
+
"numbering": [
|
|
459
|
+
1,
|
|
460
|
+
6
|
|
461
|
+
],
|
|
462
|
+
"parent": "root"
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"value": "Loading SVG from API",
|
|
466
|
+
"href": "#loading-svg-from-api",
|
|
467
|
+
"depth": 3,
|
|
468
|
+
"numbering": [
|
|
469
|
+
1,
|
|
470
|
+
6,
|
|
471
|
+
1
|
|
472
|
+
],
|
|
473
|
+
"parent": "root"
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
"value": "Fallback for invalid SVG",
|
|
477
|
+
"href": "#fallback-for-invalid-svg",
|
|
478
|
+
"depth": 3,
|
|
479
|
+
"numbering": [
|
|
480
|
+
1,
|
|
481
|
+
6,
|
|
482
|
+
2
|
|
483
|
+
],
|
|
484
|
+
"parent": "root"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"value": "Icon library from database",
|
|
488
|
+
"href": "#icon-library-from-database",
|
|
489
|
+
"depth": 3,
|
|
490
|
+
"numbering": [
|
|
491
|
+
1,
|
|
492
|
+
6,
|
|
493
|
+
3
|
|
494
|
+
],
|
|
495
|
+
"parent": "root"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
"value": "Custom icon button",
|
|
499
|
+
"href": "#custom-icon-button",
|
|
500
|
+
"depth": 3,
|
|
501
|
+
"numbering": [
|
|
502
|
+
1,
|
|
503
|
+
6,
|
|
504
|
+
4
|
|
505
|
+
],
|
|
506
|
+
"parent": "root"
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"value": "Testing your implementation",
|
|
510
|
+
"href": "#testing-your-implementation",
|
|
511
|
+
"depth": 2,
|
|
512
|
+
"numbering": [
|
|
513
|
+
1,
|
|
514
|
+
7
|
|
515
|
+
],
|
|
516
|
+
"parent": "root"
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"value": "Basic Usage Tests",
|
|
520
|
+
"href": "#basic-usage-tests",
|
|
521
|
+
"depth": 3,
|
|
522
|
+
"numbering": [
|
|
523
|
+
1,
|
|
524
|
+
7,
|
|
525
|
+
1
|
|
526
|
+
],
|
|
527
|
+
"parent": "root"
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
"value": "Security Tests",
|
|
531
|
+
"href": "#security-tests",
|
|
532
|
+
"depth": 3,
|
|
533
|
+
"numbering": [
|
|
534
|
+
1,
|
|
535
|
+
7,
|
|
536
|
+
2
|
|
537
|
+
],
|
|
538
|
+
"parent": "root"
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
"value": "Styling Tests",
|
|
542
|
+
"href": "#styling-tests",
|
|
543
|
+
"depth": 3,
|
|
544
|
+
"numbering": [
|
|
545
|
+
1,
|
|
546
|
+
7,
|
|
547
|
+
3
|
|
548
|
+
],
|
|
549
|
+
"parent": "root"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"value": "Accessibility Tests",
|
|
553
|
+
"href": "#accessibility-tests",
|
|
554
|
+
"depth": 3,
|
|
555
|
+
"numbering": [
|
|
556
|
+
1,
|
|
557
|
+
7,
|
|
558
|
+
4
|
|
559
|
+
],
|
|
560
|
+
"parent": "root"
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
"value": "Complex SVG Tests",
|
|
564
|
+
"href": "#complex-svg-tests",
|
|
565
|
+
"depth": 3,
|
|
566
|
+
"numbering": [
|
|
567
|
+
1,
|
|
568
|
+
7,
|
|
569
|
+
5
|
|
570
|
+
],
|
|
571
|
+
"parent": "root"
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
"value": "Resources",
|
|
575
|
+
"href": "#resources",
|
|
576
|
+
"depth": 2,
|
|
577
|
+
"numbering": [
|
|
578
|
+
1,
|
|
579
|
+
8
|
|
580
|
+
],
|
|
581
|
+
"parent": "root"
|
|
582
|
+
}
|
|
583
|
+
]
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|