@bettercms-ai/kit 0.1.0 → 1.0.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/_virtual/_rolldown/runtime.js +13 -0
- package/adapters/icons.d.ts +15 -0
- package/adapters/icons.js +27 -0
- package/adapters/icons.js.map +1 -0
- package/adapters/lossy.d.ts +267 -0
- package/adapters/lossy.js +233 -0
- package/adapters/lossy.js.map +1 -0
- package/adapters/prod-types.d.ts +468 -0
- package/adapters/prod-types.js +646 -0
- package/adapters/prod-types.js.map +1 -0
- package/adapters/schema.d.ts +115 -0
- package/adapters/schema.js +2203 -0
- package/adapters/schema.js.map +1 -0
- package/adapters/values.d.ts +200 -0
- package/adapters/values.js +553 -0
- package/adapters/values.js.map +1 -0
- package/brand/logo.d.ts +17 -0
- package/brand/logo.js +9 -0
- package/brand/logo.js.map +1 -0
- package/context.d.ts +269 -0
- package/context.js +214 -0
- package/context.js.map +1 -0
- package/controls/button.d.ts +58 -0
- package/controls/button.js +507 -0
- package/controls/button.js.map +1 -0
- package/controls/c1.d.ts +11 -0
- package/controls/c1.js +24 -0
- package/controls/c1.js.map +1 -0
- package/controls/c2.d.ts +10 -0
- package/controls/c2.js +19 -0
- package/controls/c2.js.map +1 -0
- package/controls/choice.d.ts +39 -0
- package/controls/choice.js +410 -0
- package/controls/choice.js.map +1 -0
- package/controls/code-register.d.ts +1 -0
- package/controls/code-register.js +8 -0
- package/controls/code-register.js.map +1 -0
- package/controls/code.d.ts +42 -0
- package/controls/code.js +396 -0
- package/controls/code.js.map +1 -0
- package/controls/color.d.ts +5 -0
- package/controls/color.js +130 -0
- package/controls/color.js.map +1 -0
- package/controls/component-services.d.ts +114 -0
- package/controls/date-register.d.ts +1 -0
- package/controls/date-register.js +9 -0
- package/controls/date-register.js.map +1 -0
- package/controls/date-zone.d.ts +104 -0
- package/controls/date-zone.js +272 -0
- package/controls/date-zone.js.map +1 -0
- package/controls/date.d.ts +7 -0
- package/controls/date.js +458 -0
- package/controls/date.js.map +1 -0
- package/controls/form-picker-register.d.ts +1 -0
- package/controls/form-picker-register.js +19 -0
- package/controls/form-picker-register.js.map +1 -0
- package/controls/form-picker.d.ts +43 -0
- package/controls/form-picker.js +83 -0
- package/controls/form-picker.js.map +1 -0
- package/controls/icon-register.d.ts +1 -0
- package/controls/icon-register.js +8 -0
- package/controls/icon-register.js.map +1 -0
- package/controls/icon.d.ts +38 -0
- package/controls/icon.js +355 -0
- package/controls/icon.js.map +1 -0
- package/controls/index.d.ts +5 -0
- package/controls/index.js +37 -0
- package/controls/index.js.map +1 -0
- package/controls/json-register.d.ts +1 -0
- package/controls/json-register.js +8 -0
- package/controls/json-register.js.map +1 -0
- package/controls/json.d.ts +2 -0
- package/controls/json.js +72 -0
- package/controls/json.js.map +1 -0
- package/controls/link.d.ts +260 -0
- package/controls/link.js +1186 -0
- package/controls/link.js.map +1 -0
- package/controls/location-register.d.ts +1 -0
- package/controls/location-register.js +8 -0
- package/controls/location-register.js.map +1 -0
- package/controls/location.d.ts +16 -0
- package/controls/location.js +197 -0
- package/controls/location.js.map +1 -0
- package/controls/media-register.d.ts +1 -0
- package/controls/media-register.js +12 -0
- package/controls/media-register.js.map +1 -0
- package/controls/media-services.d.ts +40 -0
- package/controls/media.d.ts +73 -0
- package/controls/media.js +1076 -0
- package/controls/media.js.map +1 -0
- package/controls/number.d.ts +22 -0
- package/controls/number.js +195 -0
- package/controls/number.js.map +1 -0
- package/controls/reference-register.d.ts +1 -0
- package/controls/reference-register.js +10 -0
- package/controls/reference-register.js.map +1 -0
- package/controls/reference-services.d.ts +54 -0
- package/controls/reference.d.ts +23 -0
- package/controls/reference.js +761 -0
- package/controls/reference.js.map +1 -0
- package/controls/rich-text/blocks.d.ts +28 -0
- package/controls/rich-text/blocks.js +1532 -0
- package/controls/rich-text/blocks.js.map +1 -0
- package/controls/rich-text/catalog.d.ts +98 -0
- package/controls/rich-text/catalog.js +613 -0
- package/controls/rich-text/catalog.js.map +1 -0
- package/controls/rich-text/codec.d.ts +56 -0
- package/controls/rich-text/codec.js +32 -0
- package/controls/rich-text/codec.js.map +1 -0
- package/controls/rich-text/component-card.d.ts +14 -0
- package/controls/rich-text/component-card.js +706 -0
- package/controls/rich-text/component-card.js.map +1 -0
- package/controls/rich-text/control.d.ts +21 -0
- package/controls/rich-text/control.js +254 -0
- package/controls/rich-text/control.js.map +1 -0
- package/controls/rich-text/dom.d.ts +190 -0
- package/controls/rich-text/dom.js +690 -0
- package/controls/rich-text/dom.js.map +1 -0
- package/controls/rich-text/editor.d.ts +50 -0
- package/controls/rich-text/editor.js +1530 -0
- package/controls/rich-text/editor.js.map +1 -0
- package/controls/rich-text/floating.d.ts +23 -0
- package/controls/rich-text/floating.js +137 -0
- package/controls/rich-text/floating.js.map +1 -0
- package/controls/rich-text/index.d.ts +1 -0
- package/controls/rich-text/index.js +12 -0
- package/controls/rich-text/index.js.map +1 -0
- package/controls/rich-text/link-form.d.ts +13 -0
- package/controls/rich-text/link-form.js +111 -0
- package/controls/rich-text/link-form.js.map +1 -0
- package/controls/rich-text/markdown.d.ts +6 -0
- package/controls/rich-text/markdown.js +179 -0
- package/controls/rich-text/markdown.js.map +1 -0
- package/controls/rich-text/ops.d.ts +35 -0
- package/controls/rich-text/ops.js +314 -0
- package/controls/rich-text/ops.js.map +1 -0
- package/controls/rich-text/toolbar.d.ts +85 -0
- package/controls/rich-text/toolbar.js +338 -0
- package/controls/rich-text/toolbar.js.map +1 -0
- package/controls/scale.d.ts +56 -0
- package/controls/scale.js +563 -0
- package/controls/scale.js.map +1 -0
- package/controls/slot-register.d.ts +1 -0
- package/controls/slot-register.js +16 -0
- package/controls/slot-register.js.map +1 -0
- package/controls/slot-services.d.ts +97 -0
- package/controls/slot-services.js +38 -0
- package/controls/slot-services.js.map +1 -0
- package/controls/slot.d.ts +33 -0
- package/controls/slot.js +348 -0
- package/controls/slot.js.map +1 -0
- package/controls/table/index.d.ts +1 -0
- package/controls/table/index.js +12 -0
- package/controls/table/index.js.map +1 -0
- package/controls/table/prod.d.ts +21 -0
- package/controls/table/prod.js +79 -0
- package/controls/table/prod.js.map +1 -0
- package/controls/table/refs.d.ts +50 -0
- package/controls/table/refs.js +68 -0
- package/controls/table/refs.js.map +1 -0
- package/controls/table/stored.d.ts +15 -0
- package/controls/table/stored.js +44 -0
- package/controls/table/stored.js.map +1 -0
- package/controls/table/table-editor.d.ts +103 -0
- package/controls/table/table-editor.js +2722 -0
- package/controls/table/table-editor.js.map +1 -0
- package/controls/table/table-link.d.ts +24 -0
- package/controls/table/table-link.js +180 -0
- package/controls/table/table-link.js.map +1 -0
- package/controls/table/table.d.ts +9 -0
- package/controls/table/table.js +103 -0
- package/controls/table/table.js.map +1 -0
- package/controls/text.d.ts +17 -0
- package/controls/text.js +287 -0
- package/controls/text.js.map +1 -0
- package/engine/array.d.ts +101 -0
- package/engine/array.js +893 -0
- package/engine/array.js.map +1 -0
- package/engine/bits.d.ts +24 -0
- package/engine/bits.js +60 -0
- package/engine/bits.js.map +1 -0
- package/engine/breadcrumb.d.ts +45 -0
- package/engine/breadcrumb.js +87 -0
- package/engine/breadcrumb.js.map +1 -0
- package/engine/expand.d.ts +68 -0
- package/engine/expand.js +170 -0
- package/engine/expand.js.map +1 -0
- package/engine/field-list.d.ts +20 -0
- package/engine/field-list.js +19 -0
- package/engine/field-list.js.map +1 -0
- package/engine/field-shell.d.ts +49 -0
- package/engine/field-shell.js +860 -0
- package/engine/field-shell.js.map +1 -0
- package/engine/frame.d.ts +120 -0
- package/engine/frame.js +599 -0
- package/engine/frame.js.map +1 -0
- package/engine/group-summary.d.ts +4 -0
- package/engine/group-summary.js +66 -0
- package/engine/group-summary.js.map +1 -0
- package/engine/grouping.d.ts +224 -0
- package/engine/grouping.js +824 -0
- package/engine/grouping.js.map +1 -0
- package/engine/item-list.d.ts +89 -0
- package/engine/item-list.js +703 -0
- package/engine/item-list.js.map +1 -0
- package/engine/kit-field.d.ts +72 -0
- package/engine/kit-field.js +523 -0
- package/engine/kit-field.js.map +1 -0
- package/engine/schema-form.d.ts +91 -0
- package/engine/schema-form.js +320 -0
- package/engine/schema-form.js.map +1 -0
- package/engine/slot.d.ts +13 -0
- package/engine/slot.js +226 -0
- package/engine/slot.js.map +1 -0
- package/index.d.ts +46 -0
- package/index.js +55 -0
- package/index.js.map +1 -0
- package/kit.css +56 -0
- package/lib/cn.d.ts +4 -0
- package/lib/cn.js +53 -0
- package/lib/cn.js.map +1 -0
- package/lib/columns.d.ts +14 -0
- package/lib/columns.js +27 -0
- package/lib/columns.js.map +1 -0
- package/lib/frames.d.ts +36 -0
- package/lib/frames.js +214 -0
- package/lib/frames.js.map +1 -0
- package/lib/icons.d.ts +16 -0
- package/lib/icons.js +172 -0
- package/lib/icons.js.map +1 -0
- package/lib/path.d.ts +29 -0
- package/lib/path.js +64 -0
- package/lib/path.js.map +1 -0
- package/lib/schema.d.ts +49 -0
- package/lib/schema.js +287 -0
- package/lib/schema.js.map +1 -0
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +37 -0
- package/lib/utils.js.map +1 -0
- package/lib/validate.d.ts +20 -0
- package/lib/validate.js +150 -0
- package/lib/validate.js.map +1 -0
- package/package.json +31 -59
- package/schema/adapters.d.ts +28 -0
- package/schema/adapters.js +493 -0
- package/schema/adapters.js.map +1 -0
- package/schema/help.d.ts +25 -0
- package/schema/help.js +54 -0
- package/schema/help.js.map +1 -0
- package/schema/scale.d.ts +69 -0
- package/schema/scale.js +250 -0
- package/schema/scale.js.map +1 -0
- package/schema/sources.d.ts +103 -0
- package/schema/sources.js +65 -0
- package/schema/sources.js.map +1 -0
- package/schema/table.d.ts +319 -0
- package/schema/table.js +1198 -0
- package/schema/table.js.map +1 -0
- package/schema/types.d.ts +269 -0
- package/schema/types.js +14 -0
- package/schema/types.js.map +1 -0
- package/types.d.ts +17 -0
- package/ui/action-tray.d.ts +54 -0
- package/ui/action-tray.js +153 -0
- package/ui/action-tray.js.map +1 -0
- package/ui/button.d.ts +57 -0
- package/ui/button.js +202 -0
- package/ui/button.js.map +1 -0
- package/ui/choice-switch.d.ts +36 -0
- package/ui/choice-switch.js +57 -0
- package/ui/choice-switch.js.map +1 -0
- package/ui/controls.d.ts +83 -0
- package/ui/controls.js +319 -0
- package/ui/controls.js.map +1 -0
- package/ui/display.d.ts +156 -0
- package/ui/display.js +444 -0
- package/ui/display.js.map +1 -0
- package/ui/expanded-editor-modal.d.ts +26 -0
- package/ui/expanded-editor-modal.js +140 -0
- package/ui/expanded-editor-modal.js.map +1 -0
- package/ui/field-context.d.ts +12 -0
- package/ui/field-context.js +23 -0
- package/ui/field-context.js.map +1 -0
- package/ui/floating-panel.d.ts +152 -0
- package/ui/floating-panel.js +912 -0
- package/ui/floating-panel.js.map +1 -0
- package/ui/index.d.ts +12 -0
- package/ui/index.js +13 -0
- package/ui/input.d.ts +78 -0
- package/ui/input.js +250 -0
- package/ui/input.js.map +1 -0
- package/ui/mode-bar.d.ts +31 -0
- package/ui/mode-bar.js +65 -0
- package/ui/mode-bar.js.map +1 -0
- package/ui/overlay.d.ts +123 -0
- package/ui/overlay.js +378 -0
- package/ui/overlay.js.map +1 -0
- package/ui/path-crumbs.d.ts +90 -0
- package/ui/path-crumbs.js +532 -0
- package/ui/path-crumbs.js.map +1 -0
- package/ui/presence.d.ts +16 -0
- package/ui/presence.js +65 -0
- package/ui/presence.js.map +1 -0
- package/ui/select.d.ts +66 -0
- package/ui/select.js +405 -0
- package/ui/select.js.map +1 -0
- package/ui/shortcut-hint.d.ts +14 -0
- package/ui/shortcut-hint.js +35 -0
- package/ui/shortcut-hint.js.map +1 -0
- package/ui/surfaces.d.ts +23 -0
- package/ui/surfaces.js +26 -0
- package/ui/surfaces.js.map +1 -0
- package/ui/tooltip-root.d.ts +12 -0
- package/ui/tooltip-root.js +76 -0
- package/ui/tooltip-root.js.map +1 -0
- package/ui/variants.d.ts +15 -0
- package/ui/variants.js +14 -0
- package/ui/variants.js.map +1 -0
- package/LICENSE +0 -21
- package/README.md +0 -27
- package/dist/_chunks-cjs/_visual-editing.js +0 -5898
- package/dist/_chunks-cjs/refractor.js +0 -22
- package/dist/_chunks-es/_visual-editing.mjs +0 -5904
- package/dist/_chunks-es/refractor.mjs +0 -25
- package/dist/_color.d.mts +0 -119
- package/dist/_color.d.ts +0 -119
- package/dist/_color.js +0 -1412
- package/dist/_color.mjs +0 -1411
- package/dist/_visual-editing.d.mts +0 -1126
- package/dist/_visual-editing.d.ts +0 -1126
- package/dist/_visual-editing.js +0 -30
- package/dist/_visual-editing.mjs +0 -30
- package/dist/index.d.mts +0 -3140
- package/dist/index.d.ts +0 -3140
- package/dist/index.js +0 -2036
- package/dist/index.mjs +0 -2044
- package/dist/theme.d.mts +0 -1506
- package/dist/theme.d.ts +0 -1506
- package/dist/theme.js +0 -4126
- package/dist/theme.mjs +0 -4126
- package/exports/_visual-editing.ts +0 -31
- package/exports/index.ts +0 -1
- package/exports/theme.ts +0 -1
- package/src/color/index.d.mts +0 -119
- package/src/color/index.mjs +0 -1411
- package/src/core/__workshop__/constants.ts +0 -293
- package/src/core/_compat.ts +0 -264
- package/src/core/components/autocomplete/__mocks__/apiStore.ts +0 -49
- package/src/core/components/autocomplete/__mocks__/countries.ts +0 -245
- package/src/core/components/autocomplete/__workshop__/async.tsx +0 -156
- package/src/core/components/autocomplete/__workshop__/constrainedHeight.tsx +0 -137
- package/src/core/components/autocomplete/__workshop__/custom.tsx +0 -89
- package/src/core/components/autocomplete/__workshop__/example.tsx +0 -79
- package/src/core/components/autocomplete/__workshop__/focusAndBlur.tsx +0 -36
- package/src/core/components/autocomplete/__workshop__/fullscreen.tsx +0 -294
- package/src/core/components/autocomplete/__workshop__/index.ts +0 -39
- package/src/core/components/autocomplete/__workshop__/types.ts +0 -4
- package/src/core/components/autocomplete/autocomplete.styles.tsx +0 -39
- package/src/core/components/autocomplete/autocomplete.tsx +0 -767
- package/src/core/components/autocomplete/autocompleteOption.tsx +0 -45
- package/src/core/components/autocomplete/autocompleteReducer.ts +0 -47
- package/src/core/components/autocomplete/constants.ts +0 -28
- package/src/core/components/autocomplete/index.ts +0 -2
- package/src/core/components/autocomplete/types.ts +0 -108
- package/src/core/components/breadcrumbs/__workshop__/example.tsx +0 -62
- package/src/core/components/breadcrumbs/__workshop__/index.ts +0 -14
- package/src/core/components/breadcrumbs/breadcrumbs.styles.ts +0 -18
- package/src/core/components/breadcrumbs/breadcrumbs.test.tsx +0 -51
- package/src/core/components/breadcrumbs/breadcrumbs.tsx +0 -133
- package/src/core/components/breadcrumbs/index.ts +0 -1
- package/src/core/components/dialog/__workshop__/activate.tsx +0 -134
- package/src/core/components/dialog/__workshop__/autoFocus.tsx +0 -29
- package/src/core/components/dialog/__workshop__/index.ts +0 -19
- package/src/core/components/dialog/__workshop__/layering.tsx +0 -41
- package/src/core/components/dialog/__workshop__/nested.tsx +0 -72
- package/src/core/components/dialog/__workshop__/onScroll.tsx +0 -39
- package/src/core/components/dialog/__workshop__/panes.tsx +0 -82
- package/src/core/components/dialog/__workshop__/position.tsx +0 -30
- package/src/core/components/dialog/__workshop__/props.tsx +0 -75
- package/src/core/components/dialog/__workshop__/provider.tsx +0 -11
- package/src/core/components/dialog/__workshop__/wrapped.tsx +0 -76
- package/src/core/components/dialog/dialog.tsx +0 -430
- package/src/core/components/dialog/dialogContext.ts +0 -20
- package/src/core/components/dialog/dialogProvider.tsx +0 -35
- package/src/core/components/dialog/index.ts +0 -4
- package/src/core/components/dialog/styles.ts +0 -77
- package/src/core/components/dialog/useDialog.ts +0 -11
- package/src/core/components/hotkeys/__workshop__/index.ts +0 -14
- package/src/core/components/hotkeys/__workshop__/plain.tsx +0 -9
- package/src/core/components/hotkeys/hotkeys.test.tsx +0 -42
- package/src/core/components/hotkeys/hotkeys.tsx +0 -66
- package/src/core/components/hotkeys/index.ts +0 -1
- package/src/core/components/index.ts +0 -9
- package/src/core/components/menu/__workshop__/asComponent.tsx +0 -45
- package/src/core/components/menu/__workshop__/avatarMenu.tsx +0 -51
- package/src/core/components/menu/__workshop__/closableMenuButton.tsx +0 -46
- package/src/core/components/menu/__workshop__/constrainedInBoundary.tsx +0 -134
- package/src/core/components/menu/__workshop__/customMenuItem.tsx +0 -45
- package/src/core/components/menu/__workshop__/customSelectedState.tsx +0 -39
- package/src/core/components/menu/__workshop__/disableFocusOnClose.tsx +0 -40
- package/src/core/components/menu/__workshop__/groups.tsx +0 -156
- package/src/core/components/menu/__workshop__/index.ts +0 -89
- package/src/core/components/menu/__workshop__/menuButton.tsx +0 -80
- package/src/core/components/menu/__workshop__/menuGroupRight.tsx +0 -58
- package/src/core/components/menu/__workshop__/nestedMenu.tsx +0 -22
- package/src/core/components/menu/__workshop__/onCloseMenuButton.tsx +0 -41
- package/src/core/components/menu/__workshop__/selectedItem.tsx +0 -69
- package/src/core/components/menu/__workshop__/shouldFocus.tsx +0 -47
- package/src/core/components/menu/__workshop__/tones.tsx +0 -25
- package/src/core/components/menu/__workshop__/withoutArrow.tsx +0 -32
- package/src/core/components/menu/helpers.ts +0 -82
- package/src/core/components/menu/index.ts +0 -5
- package/src/core/components/menu/menu.spacing.test.tsx +0 -63
- package/src/core/components/menu/menu.test.tsx +0 -125
- package/src/core/components/menu/menu.tsx +0 -178
- package/src/core/components/menu/menuButton.tsx +0 -268
- package/src/core/components/menu/menuContext.ts +0 -18
- package/src/core/components/menu/menuDivider.ts +0 -23
- package/src/core/components/menu/menuGroup.spacing.test.tsx +0 -63
- package/src/core/components/menu/menuGroup.tsx +0 -233
- package/src/core/components/menu/menuItem.spacing.test.tsx +0 -59
- package/src/core/components/menu/menuItem.tsx +0 -197
- package/src/core/components/menu/useMenu.ts +0 -21
- package/src/core/components/menu/useMenuController.ts +0 -231
- package/src/core/components/skeleton/__workshop__/delay.tsx +0 -70
- package/src/core/components/skeleton/__workshop__/index.ts +0 -11
- package/src/core/components/skeleton/__workshop__/skeleton.tsx +0 -64
- package/src/core/components/skeleton/index.ts +0 -2
- package/src/core/components/skeleton/skeleton.tsx +0 -57
- package/src/core/components/skeleton/styles.ts +0 -50
- package/src/core/components/skeleton/textSkeleton.tsx +0 -122
- package/src/core/components/tab/__workshop__/example.tsx +0 -79
- package/src/core/components/tab/__workshop__/index.ts +0 -14
- package/src/core/components/tab/index.ts +0 -3
- package/src/core/components/tab/tab.tsx +0 -101
- package/src/core/components/tab/tabList.test.tsx +0 -48
- package/src/core/components/tab/tabList.tsx +0 -70
- package/src/core/components/tab/tabPanel.tsx +0 -39
- package/src/core/components/toast/__workshop__/hook.tsx +0 -71
- package/src/core/components/toast/__workshop__/index.ts +0 -19
- package/src/core/components/toast/__workshop__/toast.tsx +0 -26
- package/src/core/components/toast/index.ts +0 -4
- package/src/core/components/toast/styles.ts +0 -77
- package/src/core/components/toast/toast.test.tsx +0 -101
- package/src/core/components/toast/toast.tsx +0 -198
- package/src/core/components/toast/toastContext.ts +0 -7
- package/src/core/components/toast/toastLayer.tsx +0 -51
- package/src/core/components/toast/toastProvider.tsx +0 -113
- package/src/core/components/toast/toastState.ts +0 -6
- package/src/core/components/toast/types.ts +0 -26
- package/src/core/components/toast/useToast.ts +0 -25
- package/src/core/components/tree/__workshop__/basic.perf.ts +0 -19
- package/src/core/components/tree/__workshop__/basic.tsx +0 -105
- package/src/core/components/tree/__workshop__/index.ts +0 -21
- package/src/core/components/tree/__workshop__/tabFromElement.tsx +0 -84
- package/src/core/components/tree/helpers.ts +0 -105
- package/src/core/components/tree/index.ts +0 -4
- package/src/core/components/tree/style.ts +0 -105
- package/src/core/components/tree/tree.test.tsx +0 -55
- package/src/core/components/tree/tree.tsx +0 -240
- package/src/core/components/tree/treeContext.ts +0 -10
- package/src/core/components/tree/treeGroup.tsx +0 -28
- package/src/core/components/tree/treeItem.test.tsx +0 -65
- package/src/core/components/tree/treeItem.tsx +0 -224
- package/src/core/components/tree/types.ts +0 -25
- package/src/core/components/tree/useTree.ts +0 -17
- package/src/core/constants.ts +0 -79
- package/src/core/helpers/animation.ts +0 -27
- package/src/core/helpers/element.ts +0 -55
- package/src/core/helpers/focus.ts +0 -100
- package/src/core/helpers/index.ts +0 -4
- package/src/core/helpers/scroll.ts +0 -15
- package/src/core/hooks/index.ts +0 -12
- package/src/core/hooks/useArrayProp.ts +0 -17
- package/src/core/hooks/useClickOutside.test.tsx +0 -482
- package/src/core/hooks/useClickOutside.ts +0 -118
- package/src/core/hooks/useClickOutsideEvent.test.tsx +0 -115
- package/src/core/hooks/useClickOutsideEvent.ts +0 -73
- package/src/core/hooks/useCustomValidity.ts +0 -13
- package/src/core/hooks/useDelayed.test.ts +0 -88
- package/src/core/hooks/useDelayedState.ts +0 -36
- package/src/core/hooks/useElementRect/__workshop__/example.tsx +0 -32
- package/src/core/hooks/useElementRect/__workshop__/index.ts +0 -14
- package/src/core/hooks/useElementRect/index.ts +0 -1
- package/src/core/hooks/useElementRect/useElementRect.ts +0 -13
- package/src/core/hooks/useElementSize.ts +0 -19
- package/src/core/hooks/useForwardedRef.ts +0 -19
- package/src/core/hooks/useGlobalKeyDown.ts +0 -24
- package/src/core/hooks/useIsomorphicEffect.ts +0 -7
- package/src/core/hooks/useMatchMedia.ts +0 -28
- package/src/core/hooks/useMediaIndex/__workshop__/index.ts +0 -14
- package/src/core/hooks/useMediaIndex/__workshop__/test.tsx +0 -14
- package/src/core/hooks/useMediaIndex/index.ts +0 -1
- package/src/core/hooks/useMediaIndex/useMediaIndex.test.tsx +0 -36
- package/src/core/hooks/useMediaIndex/useMediaIndex.ts +0 -102
- package/src/core/hooks/useMounted.ts +0 -15
- package/src/core/hooks/usePrefersDark.hydration.test.tsx +0 -56
- package/src/core/hooks/usePrefersDark.test.tsx +0 -19
- package/src/core/hooks/usePrefersDark.ts +0 -16
- package/src/core/hooks/usePrefersReducedMotion.hydration.test.tsx +0 -56
- package/src/core/hooks/usePrefersReducedMotion.test.tsx +0 -19
- package/src/core/hooks/usePrefersReducedMotion.ts +0 -16
- package/src/core/index.ts +0 -10
- package/src/core/lib/createGlobalScopedContext.ts +0 -36
- package/src/core/lib/globalScope.ts +0 -19
- package/src/core/lib/isRecord.ts +0 -3
- package/src/core/middleware/origin.ts +0 -47
- package/src/core/observers/elementSizeObserver.ts +0 -116
- package/src/core/observers/index.ts +0 -2
- package/src/core/observers/resizeObserver.ts +0 -9
- package/src/core/primitives/_selectable/index.ts +0 -1
- package/src/core/primitives/_selectable/selectable.tsx +0 -15
- package/src/core/primitives/_selectable/style.ts +0 -115
- package/src/core/primitives/avatar/__workshop__/asButton.tsx +0 -14
- package/src/core/primitives/avatar/__workshop__/index.ts +0 -29
- package/src/core/primitives/avatar/__workshop__/stack.tsx +0 -25
- package/src/core/primitives/avatar/__workshop__/withinButton.tsx +0 -63
- package/src/core/primitives/avatar/__workshop__/withinMenuItem.tsx +0 -70
- package/src/core/primitives/avatar/avatar.tsx +0 -200
- package/src/core/primitives/avatar/avatarCounter.tsx +0 -91
- package/src/core/primitives/avatar/avatarStack.tsx +0 -100
- package/src/core/primitives/avatar/index.ts +0 -4
- package/src/core/primitives/avatar/styles.ts +0 -167
- package/src/core/primitives/avatar/types.ts +0 -17
- package/src/core/primitives/badge/__workshop__/index.ts +0 -19
- package/src/core/primitives/badge/__workshop__/props.tsx +0 -30
- package/src/core/primitives/badge/__workshop__/tones.tsx +0 -21
- package/src/core/primitives/badge/badge.test.tsx +0 -16
- package/src/core/primitives/badge/badge.tsx +0 -70
- package/src/core/primitives/badge/index.ts +0 -1
- package/src/core/primitives/badge/styles.ts +0 -20
- package/src/core/primitives/badge/types.ts +0 -8
- package/src/core/primitives/box/__workshop__/asComponent.tsx +0 -31
- package/src/core/primitives/box/__workshop__/index.ts +0 -24
- package/src/core/primitives/box/__workshop__/props.tsx +0 -20
- package/src/core/primitives/box/__workshop__/responsive.tsx +0 -20
- package/src/core/primitives/box/box.test.tsx +0 -142
- package/src/core/primitives/box/box.tsx +0 -154
- package/src/core/primitives/box/index.ts +0 -1
- package/src/core/primitives/button/__workshop__/custom.tsx +0 -51
- package/src/core/primitives/button/__workshop__/customIcons.tsx +0 -30
- package/src/core/primitives/button/__workshop__/disabled.tsx +0 -74
- package/src/core/primitives/button/__workshop__/index.ts +0 -59
- package/src/core/primitives/button/__workshop__/labelUploadButton.tsx +0 -36
- package/src/core/primitives/button/__workshop__/mixedChildren.tsx +0 -12
- package/src/core/primitives/button/__workshop__/props.tsx +0 -55
- package/src/core/primitives/button/__workshop__/stacked.tsx +0 -58
- package/src/core/primitives/button/__workshop__/styled1.tsx +0 -17
- package/src/core/primitives/button/__workshop__/styled2.tsx +0 -19
- package/src/core/primitives/button/__workshop__/uploadButton.tsx +0 -28
- package/src/core/primitives/button/button.test.tsx +0 -82
- package/src/core/primitives/button/button.tsx +0 -210
- package/src/core/primitives/button/index.ts +0 -1
- package/src/core/primitives/button/styles.ts +0 -117
- package/src/core/primitives/card/__workshop__/allTones.tsx +0 -25
- package/src/core/primitives/card/__workshop__/asButton.tsx +0 -107
- package/src/core/primitives/card/__workshop__/asComponent.tsx +0 -27
- package/src/core/primitives/card/__workshop__/checkered.tsx +0 -26
- package/src/core/primitives/card/__workshop__/index.ts +0 -18
- package/src/core/primitives/card/__workshop__/interactive.tsx +0 -30
- package/src/core/primitives/card/__workshop__/listNavigation.tsx +0 -80
- package/src/core/primitives/card/__workshop__/props.tsx +0 -53
- package/src/core/primitives/card/__workshop__/selected.tsx +0 -94
- package/src/core/primitives/card/__workshop__/styled.tsx +0 -14
- package/src/core/primitives/card/card.tsx +0 -128
- package/src/core/primitives/card/index.ts +0 -2
- package/src/core/primitives/card/styles.ts +0 -147
- package/src/core/primitives/card/types.ts +0 -11
- package/src/core/primitives/checkbox/__workshop__/example.tsx +0 -25
- package/src/core/primitives/checkbox/__workshop__/index.ts +0 -13
- package/src/core/primitives/checkbox/__workshop__/props.tsx +0 -33
- package/src/core/primitives/checkbox/__workshop__/readOnly.tsx +0 -16
- package/src/core/primitives/checkbox/__workshop__/tones.tsx +0 -28
- package/src/core/primitives/checkbox/checkbox.tsx +0 -73
- package/src/core/primitives/checkbox/index.ts +0 -1
- package/src/core/primitives/checkbox/styles.ts +0 -128
- package/src/core/primitives/code/__workshop__/index.ts +0 -19
- package/src/core/primitives/code/__workshop__/opticalAlignment.tsx +0 -48
- package/src/core/primitives/code/__workshop__/props.tsx +0 -21
- package/src/core/primitives/code/code.tsx +0 -55
- package/src/core/primitives/code/index.ts +0 -1
- package/src/core/primitives/code/refractor.tsx +0 -20
- package/src/core/primitives/code/styles.ts +0 -77
- package/src/core/primitives/container/__workshop__/example.tsx +0 -20
- package/src/core/primitives/container/__workshop__/index.ts +0 -8
- package/src/core/primitives/container/container.tsx +0 -54
- package/src/core/primitives/container/index.ts +0 -2
- package/src/core/primitives/container/styles.ts +0 -23
- package/src/core/primitives/container/types.ts +0 -6
- package/src/core/primitives/flex/__workshop__/example.tsx +0 -34
- package/src/core/primitives/flex/__workshop__/gap.tsx +0 -25
- package/src/core/primitives/flex/__workshop__/index.ts +0 -11
- package/src/core/primitives/flex/flex.tsx +0 -64
- package/src/core/primitives/flex/index.ts +0 -1
- package/src/core/primitives/grid/__workshop__/index.ts +0 -10
- package/src/core/primitives/grid/__workshop__/responsive.tsx +0 -54
- package/src/core/primitives/grid/grid.test.tsx +0 -80
- package/src/core/primitives/grid/grid.tsx +0 -74
- package/src/core/primitives/grid/index.ts +0 -1
- package/src/core/primitives/heading/__workshop__/index.ts +0 -19
- package/src/core/primitives/heading/__workshop__/opticalAlignment.tsx +0 -54
- package/src/core/primitives/heading/__workshop__/plain.tsx +0 -32
- package/src/core/primitives/heading/heading.tsx +0 -88
- package/src/core/primitives/heading/index.ts +0 -1
- package/src/core/primitives/heading/styles.ts +0 -64
- package/src/core/primitives/heading/types.ts +0 -7
- package/src/core/primitives/index.ts +0 -27
- package/src/core/primitives/inline/__workshop__/index.ts +0 -8
- package/src/core/primitives/inline/__workshop__/plain.tsx +0 -27
- package/src/core/primitives/inline/index.ts +0 -1
- package/src/core/primitives/inline/inline.test.tsx +0 -51
- package/src/core/primitives/inline/inline.tsx +0 -63
- package/src/core/primitives/inline/styles.ts +0 -32
- package/src/core/primitives/inline/types.ts +0 -6
- package/src/core/primitives/kbd/__workshop__/index.ts +0 -8
- package/src/core/primitives/kbd/__workshop__/plain.tsx +0 -9
- package/src/core/primitives/kbd/index.ts +0 -1
- package/src/core/primitives/kbd/kbd.tsx +0 -69
- package/src/core/primitives/label/__workshop__/index.ts +0 -19
- package/src/core/primitives/label/__workshop__/opticalAlignment.tsx +0 -48
- package/src/core/primitives/label/__workshop__/plain.tsx +0 -24
- package/src/core/primitives/label/index.ts +0 -1
- package/src/core/primitives/label/label.tsx +0 -87
- package/src/core/primitives/label/styles.ts +0 -45
- package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +0 -77
- package/src/core/primitives/popover/__workshop__/MarginsStory.tsx +0 -31
- package/src/core/primitives/popover/__workshop__/MatchReferenceWidthStory.tsx +0 -32
- package/src/core/primitives/popover/__workshop__/OpenOnMountStory.tsx +0 -11
- package/src/core/primitives/popover/__workshop__/PlainStory.tsx +0 -71
- package/src/core/primitives/popover/__workshop__/RecursiveStory.tsx +0 -71
- package/src/core/primitives/popover/__workshop__/SidePanelStory.tsx +0 -89
- package/src/core/primitives/popover/__workshop__/TestStory.tsx +0 -97
- package/src/core/primitives/popover/__workshop__/index.ts +0 -49
- package/src/core/primitives/popover/constants.ts +0 -22
- package/src/core/primitives/popover/floating-ui/size.ts +0 -99
- package/src/core/primitives/popover/helpers.ts +0 -31
- package/src/core/primitives/popover/index.ts +0 -2
- package/src/core/primitives/popover/popover.tsx +0 -511
- package/src/core/primitives/popover/popoverCard.tsx +0 -166
- package/src/core/primitives/popover/types.ts +0 -7
- package/src/core/primitives/radio/__workshop__/example.tsx +0 -63
- package/src/core/primitives/radio/__workshop__/index.ts +0 -11
- package/src/core/primitives/radio/__workshop__/plain.tsx +0 -28
- package/src/core/primitives/radio/index.ts +0 -1
- package/src/core/primitives/radio/radio.tsx +0 -51
- package/src/core/primitives/radio/styles.ts +0 -117
- package/src/core/primitives/select/__workshop__/index.ts +0 -11
- package/src/core/primitives/select/__workshop__/plain.tsx +0 -27
- package/src/core/primitives/select/__workshop__/readOnly.tsx +0 -23
- package/src/core/primitives/select/index.ts +0 -1
- package/src/core/primitives/select/select.test.tsx +0 -52
- package/src/core/primitives/select/select.tsx +0 -94
- package/src/core/primitives/select/styles.ts +0 -166
- package/src/core/primitives/spinner/__workshop__/Props.tsx +0 -15
- package/src/core/primitives/spinner/__workshop__/index.ts +0 -14
- package/src/core/primitives/spinner/index.ts +0 -1
- package/src/core/primitives/spinner/spinner.tsx +0 -46
- package/src/core/primitives/stack/__workshop__/index.ts +0 -14
- package/src/core/primitives/stack/__workshop__/plain.tsx +0 -32
- package/src/core/primitives/stack/index.ts +0 -1
- package/src/core/primitives/stack/stack.test.tsx +0 -57
- package/src/core/primitives/stack/stack.tsx +0 -57
- package/src/core/primitives/stack/styles.ts +0 -32
- package/src/core/primitives/switch/__workshop__/example.tsx +0 -23
- package/src/core/primitives/switch/__workshop__/index.ts +0 -11
- package/src/core/primitives/switch/__workshop__/props.tsx +0 -21
- package/src/core/primitives/switch/index.ts +0 -1
- package/src/core/primitives/switch/styles.ts +0 -173
- package/src/core/primitives/switch/switch.tsx +0 -68
- package/src/core/primitives/text/__workshop__/colored.tsx +0 -30
- package/src/core/primitives/text/__workshop__/example.tsx +0 -39
- package/src/core/primitives/text/__workshop__/index.ts +0 -24
- package/src/core/primitives/text/__workshop__/opticalAlignment.tsx +0 -48
- package/src/core/primitives/text/index.ts +0 -1
- package/src/core/primitives/text/styles.ts +0 -74
- package/src/core/primitives/text/text.tsx +0 -89
- package/src/core/primitives/textArea/__workshop__/index.ts +0 -14
- package/src/core/primitives/textArea/__workshop__/plain.tsx +0 -50
- package/src/core/primitives/textArea/index.ts +0 -1
- package/src/core/primitives/textArea/textArea.tsx +0 -120
- package/src/core/primitives/textInput/__workshop__/clearButton.tsx +0 -30
- package/src/core/primitives/textInput/__workshop__/customValidity.tsx +0 -17
- package/src/core/primitives/textInput/__workshop__/index.ts +0 -44
- package/src/core/primitives/textInput/__workshop__/plain.tsx +0 -98
- package/src/core/primitives/textInput/__workshop__/readOnly.tsx +0 -9
- package/src/core/primitives/textInput/__workshop__/states.tsx +0 -53
- package/src/core/primitives/textInput/__workshop__/tones.tsx +0 -277
- package/src/core/primitives/textInput/__workshop__/typed.tsx +0 -23
- package/src/core/primitives/textInput/index.ts +0 -1
- package/src/core/primitives/textInput/textInput.test.tsx +0 -48
- package/src/core/primitives/textInput/textInput.tsx +0 -395
- package/src/core/primitives/tooltip/__workshop__/customPortal.tsx +0 -102
- package/src/core/primitives/tooltip/__workshop__/index.ts +0 -29
- package/src/core/primitives/tooltip/__workshop__/overflowingBoundary.tsx +0 -74
- package/src/core/primitives/tooltip/__workshop__/props.tsx +0 -107
- package/src/core/primitives/tooltip/__workshop__/resizableBoundary.tsx +0 -86
- package/src/core/primitives/tooltip/constants.ts +0 -23
- package/src/core/primitives/tooltip/index.ts +0 -2
- package/src/core/primitives/tooltip/tooltip.test.tsx +0 -452
- package/src/core/primitives/tooltip/tooltip.tsx +0 -495
- package/src/core/primitives/tooltip/tooltipCard.tsx +0 -109
- package/src/core/primitives/tooltip/tooltipDelayGroup/index.ts +0 -4
- package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupContext.tsx +0 -11
- package/src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx +0 -57
- package/src/core/primitives/tooltip/tooltipDelayGroup/types.ts +0 -10
- package/src/core/primitives/tooltip/tooltipDelayGroup/useTooltipDelayGroup.ts +0 -13
- package/src/core/primitives/types.ts +0 -179
- package/src/core/styles/border/borderStyle.ts +0 -56
- package/src/core/styles/border/index.ts +0 -2
- package/src/core/styles/border/types.ts +0 -10
- package/src/core/styles/box/boxStyle.ts +0 -69
- package/src/core/styles/box/index.ts +0 -2
- package/src/core/styles/box/types.ts +0 -11
- package/src/core/styles/card/_cardColorStyle.ts +0 -108
- package/src/core/styles/card/index.ts +0 -1
- package/src/core/styles/flex/flexItemStyle.ts +0 -27
- package/src/core/styles/flex/flexStyle.ts +0 -70
- package/src/core/styles/flex/index.ts +0 -3
- package/src/core/styles/flex/types.ts +0 -25
- package/src/core/styles/focusRing/index.ts +0 -25
- package/src/core/styles/font/codeFontStyle.ts +0 -13
- package/src/core/styles/font/headingFontStyle.ts +0 -13
- package/src/core/styles/font/index.ts +0 -6
- package/src/core/styles/font/labelFontStyle.ts +0 -13
- package/src/core/styles/font/responsiveFont.ts +0 -103
- package/src/core/styles/font/textAlignStyle.ts +0 -19
- package/src/core/styles/font/textFontStyle.ts +0 -13
- package/src/core/styles/font/types.ts +0 -35
- package/src/core/styles/grid/gridItemStyle.ts +0 -82
- package/src/core/styles/grid/gridStyle.ts +0 -108
- package/src/core/styles/grid/index.ts +0 -3
- package/src/core/styles/grid/types.ts +0 -37
- package/src/core/styles/helpers.ts +0 -72
- package/src/core/styles/index.ts +0 -5
- package/src/core/styles/input/index.ts +0 -2
- package/src/core/styles/input/responsiveInputPaddingStyle.ts +0 -78
- package/src/core/styles/input/textInputStyle.ts +0 -263
- package/src/core/styles/internal.ts +0 -12
- package/src/core/styles/margin/index.ts +0 -2
- package/src/core/styles/margin/marginStyle.ts +0 -21
- package/src/core/styles/margin/marginsStyle.test.ts +0 -33
- package/src/core/styles/margin/types.ts +0 -9
- package/src/core/styles/padding/index.ts +0 -2
- package/src/core/styles/padding/paddingStyle.test.ts +0 -33
- package/src/core/styles/padding/paddingStyle.ts +0 -21
- package/src/core/styles/padding/types.ts +0 -12
- package/src/core/styles/radius/index.ts +0 -2
- package/src/core/styles/radius/radiusStyle.ts +0 -23
- package/src/core/styles/radius/types.ts +0 -8
- package/src/core/styles/shadow/index.ts +0 -2
- package/src/core/styles/shadow/shadowStyle.ts +0 -29
- package/src/core/styles/shadow/types.ts +0 -6
- package/src/core/styles/types.ts +0 -8
- package/src/core/theme/__workshop__/build/Root.tsx +0 -367
- package/src/core/theme/__workshop__/build/helpers.ts +0 -46
- package/src/core/theme/__workshop__/build/story.tsx +0 -465
- package/src/core/theme/__workshop__/canvas.tsx +0 -352
- package/src/core/theme/__workshop__/color.tsx +0 -62
- package/src/core/theme/__workshop__/debug/story.tsx +0 -408
- package/src/core/theme/__workshop__/index.ts +0 -39
- package/src/core/theme/__workshop__/layer.tsx +0 -78
- package/src/core/theme/__workshop__/nestedProvider.tsx +0 -15
- package/src/core/theme/index.ts +0 -5
- package/src/core/theme/theme.test.tsx +0 -73
- package/src/core/theme/themeColorProvider.tsx +0 -29
- package/src/core/theme/themeContext.ts +0 -10
- package/src/core/theme/themeProvider.tsx +0 -62
- package/src/core/theme/types.ts +0 -12
- package/src/core/theme/useRootTheme.ts +0 -17
- package/src/core/theme/useTheme.ts +0 -16
- package/src/core/types/avatar.ts +0 -14
- package/src/core/types/badge.ts +0 -12
- package/src/core/types/box.ts +0 -19
- package/src/core/types/button.ts +0 -21
- package/src/core/types/card.ts +0 -6
- package/src/core/types/component.ts +0 -32
- package/src/core/types/dialog.ts +0 -4
- package/src/core/types/flex.ts +0 -30
- package/src/core/types/grid.ts +0 -14
- package/src/core/types/gridItem.ts +0 -29
- package/src/core/types/index.ts +0 -15
- package/src/core/types/placement.ts +0 -18
- package/src/core/types/popover.ts +0 -4
- package/src/core/types/radius.ts +0 -4
- package/src/core/types/selectable.ts +0 -6
- package/src/core/types/text.ts +0 -4
- package/src/core/utils/arrow/arrow.tsx +0 -123
- package/src/core/utils/arrow/cmds.ts +0 -91
- package/src/core/utils/arrow/index.ts +0 -1
- package/src/core/utils/boundaryElement/__workshop__/index.ts +0 -14
- package/src/core/utils/boundaryElement/__workshop__/plain.tsx +0 -19
- package/src/core/utils/boundaryElement/boundaryElement.test.tsx +0 -100
- package/src/core/utils/boundaryElement/boundaryElementContext.ts +0 -7
- package/src/core/utils/boundaryElement/boundaryElementProvider.tsx +0 -24
- package/src/core/utils/boundaryElement/index.ts +0 -3
- package/src/core/utils/boundaryElement/types.ts +0 -7
- package/src/core/utils/boundaryElement/useBoundaryElement.ts +0 -26
- package/src/core/utils/conditionalWrapper/conditionalWrapper.tsx +0 -21
- package/src/core/utils/conditionalWrapper/index.ts +0 -1
- package/src/core/utils/elementQuery/__workshop__/customMedia.tsx +0 -30
- package/src/core/utils/elementQuery/__workshop__/index.ts +0 -14
- package/src/core/utils/elementQuery/elementQuery.tsx +0 -53
- package/src/core/utils/elementQuery/helpers.ts +0 -27
- package/src/core/utils/elementQuery/index.ts +0 -1
- package/src/core/utils/errorBoundary.tsx +0 -48
- package/src/core/utils/getElementRef.ts +0 -26
- package/src/core/utils/index.ts +0 -9
- package/src/core/utils/layer/__workshop__/_debug.tsx +0 -17
- package/src/core/utils/layer/__workshop__/index.ts +0 -24
- package/src/core/utils/layer/__workshop__/multipleRoots.tsx +0 -49
- package/src/core/utils/layer/__workshop__/nested.tsx +0 -98
- package/src/core/utils/layer/__workshop__/responsiveZOffset.tsx +0 -13
- package/src/core/utils/layer/getLayerContext.test.ts +0 -30
- package/src/core/utils/layer/getLayerContext.ts +0 -21
- package/src/core/utils/layer/index.ts +0 -4
- package/src/core/utils/layer/layer.test.tsx +0 -108
- package/src/core/utils/layer/layer.tsx +0 -98
- package/src/core/utils/layer/layerContext.ts +0 -7
- package/src/core/utils/layer/layerProvider.tsx +0 -111
- package/src/core/utils/layer/types.ts +0 -9
- package/src/core/utils/layer/useLayer.ts +0 -26
- package/src/core/utils/portal/__workshop__/index.ts +0 -14
- package/src/core/utils/portal/__workshop__/named.tsx +0 -63
- package/src/core/utils/portal/index.ts +0 -4
- package/src/core/utils/portal/portal.test.tsx +0 -103
- package/src/core/utils/portal/portal.ts +0 -32
- package/src/core/utils/portal/portalContext.ts +0 -31
- package/src/core/utils/portal/portalProvider.tsx +0 -47
- package/src/core/utils/portal/types.ts +0 -9
- package/src/core/utils/portal/usePortal.ts +0 -25
- package/src/core/utils/spanWithTextOverflow.tsx +0 -10
- package/src/core/utils/srOnly/index.ts +0 -1
- package/src/core/utils/srOnly/srOnly.tsx +0 -36
- package/src/core/utils/virtualList/__workshop__/changingProps.tsx +0 -36
- package/src/core/utils/virtualList/__workshop__/elementScroll.tsx +0 -24
- package/src/core/utils/virtualList/__workshop__/index.ts +0 -29
- package/src/core/utils/virtualList/__workshop__/infiniteList.tsx +0 -48
- package/src/core/utils/virtualList/__workshop__/windowScrolll.tsx +0 -22
- package/src/core/utils/virtualList/index.ts +0 -1
- package/src/core/utils/virtualList/virtualList.tsx +0 -200
- package/src/theme/build/_deprecated/color/_selectable/createSelectableTones.ts +0 -76
- package/src/theme/build/_deprecated/color/_solid/createSolidTones.ts +0 -54
- package/src/theme/build/_deprecated/color/button/createButtonModes.ts +0 -22
- package/src/theme/build/_deprecated/color/button/createButtonTones.ts +0 -55
- package/src/theme/build/_deprecated/color/card/createCardStates.ts +0 -60
- package/src/theme/build/_deprecated/color/color.test.ts +0 -63
- package/src/theme/build/_deprecated/color/defaults.ts +0 -390
- package/src/theme/build/_deprecated/color/factory.ts +0 -142
- package/src/theme/build/_deprecated/color/index.ts +0 -1
- package/src/theme/build/_deprecated/color/input/createInputModes.ts +0 -81
- package/src/theme/build/_deprecated/color/muted/createMuted.ts +0 -54
- package/src/theme/build/_deprecated/color/spot/createSpot.ts +0 -20
- package/src/theme/build/buildColorTheme.test.ts +0 -183
- package/src/theme/build/buildColorTheme.ts +0 -499
- package/src/theme/build/buildTheme.test.ts +0 -87
- package/src/theme/build/buildTheme.ts +0 -36
- package/src/theme/build/colorToken/colorToken.ts +0 -19
- package/src/theme/build/colorToken/compileColorToken.ts +0 -21
- package/src/theme/build/colorToken/index.ts +0 -2
- package/src/theme/build/colorToken/types.ts +0 -6
- package/src/theme/build/index.ts +0 -3
- package/src/theme/build/lib/color-fns/blend/index.ts +0 -3
- package/src/theme/build/lib/color-fns/blend/mix.ts +0 -21
- package/src/theme/build/lib/color-fns/blend/multiply.ts +0 -18
- package/src/theme/build/lib/color-fns/blend/screen.ts +0 -18
- package/src/theme/build/lib/color-fns/color-fns.test.ts +0 -68
- package/src/theme/build/lib/color-fns/contrastRatio.ts +0 -31
- package/src/theme/build/lib/color-fns/convert.ts +0 -150
- package/src/theme/build/lib/color-fns/index.ts +0 -6
- package/src/theme/build/lib/color-fns/parse.ts +0 -60
- package/src/theme/build/lib/color-fns/rgba.ts +0 -10
- package/src/theme/build/lib/color-fns/types.ts +0 -28
- package/src/theme/build/lib/isRecord.ts +0 -3
- package/src/theme/build/lib/lazy.ts +0 -30
- package/src/theme/build/lib/utils.ts +0 -19
- package/src/theme/build/merge.ts +0 -26
- package/src/theme/build/mixThemeColor.test.ts +0 -21
- package/src/theme/build/mixThemeColor.ts +0 -53
- package/src/theme/build/renderColorTheme.ts +0 -532
- package/src/theme/build/renderColorValue.ts +0 -85
- package/src/theme/build/resolveColorTokens.ts +0 -268
- package/src/theme/build/theme.test.ts +0 -27
- package/src/theme/config/helpers.ts +0 -55
- package/src/theme/config/index.ts +0 -4
- package/src/theme/config/system.ts +0 -115
- package/src/theme/config/tokens/color/index.ts +0 -1
- package/src/theme/config/tokens/color/types.ts +0 -133
- package/src/theme/config/tokens/index.ts +0 -4
- package/src/theme/config/tokens/parseTokenKey.test.ts +0 -64
- package/src/theme/config/tokens/parseTokenKey.ts +0 -67
- package/src/theme/config/tokens/parseTokenValue.test.ts +0 -42
- package/src/theme/config/tokens/parseTokenValue.ts +0 -133
- package/src/theme/config/tokens/types.ts +0 -53
- package/src/theme/config/types.ts +0 -46
- package/src/theme/defaults/colorPalette.ts +0 -5
- package/src/theme/defaults/colorTokens.ts +0 -648
- package/src/theme/defaults/config.ts +0 -84
- package/src/theme/defaults/fonts.ts +0 -227
- package/src/theme/getScopedTheme.ts +0 -98
- package/src/theme/index.ts +0 -5
- package/src/theme/system/avatar.ts +0 -14
- package/src/theme/system/color/_constants.ts +0 -45
- package/src/theme/system/color/_helpers.ts +0 -24
- package/src/theme/system/color/_system.ts +0 -40
- package/src/theme/system/color/avatar.ts +0 -15
- package/src/theme/system/color/badge.ts +0 -16
- package/src/theme/system/color/button.ts +0 -17
- package/src/theme/system/color/color.ts +0 -34
- package/src/theme/system/color/index.ts +0 -13
- package/src/theme/system/color/input.ts +0 -25
- package/src/theme/system/color/kbd.ts +0 -8
- package/src/theme/system/color/selectable.ts +0 -12
- package/src/theme/system/color/shadow.ts +0 -7
- package/src/theme/system/color/state.ts +0 -43
- package/src/theme/system/color/syntax.ts +0 -41
- package/src/theme/system/css.ts +0 -14
- package/src/theme/system/focusRing.ts +0 -7
- package/src/theme/system/font.ts +0 -52
- package/src/theme/system/index.ts +0 -11
- package/src/theme/system/input.ts +0 -33
- package/src/theme/system/layer.ts +0 -8
- package/src/theme/system/shadow.ts +0 -19
- package/src/theme/system/styles.ts +0 -13
- package/src/theme/system/theme.ts +0 -138
- package/src/theme/system/v0/avatar.ts +0 -10
- package/src/theme/system/v0/color/_generic.ts +0 -35
- package/src/theme/system/v0/color/_system.ts +0 -17
- package/src/theme/system/v0/color/base.ts +0 -21
- package/src/theme/system/v0/color/button.ts +0 -42
- package/src/theme/system/v0/color/card.ts +0 -19
- package/src/theme/system/v0/color/color.ts +0 -40
- package/src/theme/system/v0/color/index.ts +0 -11
- package/src/theme/system/v0/color/input.ts +0 -34
- package/src/theme/system/v0/color/muted.ts +0 -26
- package/src/theme/system/v0/color/selectable.ts +0 -31
- package/src/theme/system/v0/color/solid.ts +0 -26
- package/src/theme/system/v0/color/spot.ts +0 -13
- package/src/theme/system/v0/index.ts +0 -3
- package/src/theme/system/v0/input.ts +0 -23
- package/src/theme/versioning/getTheme_v2.ts +0 -57
- package/src/theme/versioning/index.ts +0 -5
- package/src/theme/versioning/is_v0.ts +0 -6
- package/src/theme/versioning/is_v2.ts +0 -6
- package/src/theme/versioning/themeColor_v0_v2.ts +0 -243
- package/src/theme/versioning/themeColor_v2_v2_9.ts +0 -49
- package/src/theme/versioning/v0_v2.ts +0 -94
- package/src/theme/versioning/v2_v0.ts +0 -135
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","names":[],"sources":["../../../src/kit/controls/rich-text/editor.tsx"],"sourcesContent":["/**\n * RICH TEXT — the boxed rich-text editor (V2 HEAD controls/rich-text-editor.tsx, Figma 60995-5431, CPO D49 / D54 / D55).\n *\n * contentEditable + execCommand keeps it dependency-free; the value is clean HTML, which the field's control turns into\n * the stored value through the host's codec (./codec.ts). Rich blocks (an image) are React \"islands\" rendered into\n * contenteditable=false nodes and written back as static HTML, so a re-mount restores them (./dom.ts).\n *\n * ./toolbar.tsx the field toolbar (no room at rest, folds into the chevron by width)\n * ./catalog.tsx Insert menu, slash menu and the shared block catalogue\n * ./blocks.tsx the rich blocks (an image)\n * ./markdown.ts HTML ⇄ Markdown for the Markdown toggle and pasting\n * ./ops.ts pure DOM block operations (insert, turn into, move, duplicate, live Markdown, field rules)\n * ./floating.tsx the selection bubble\n * ./dom.ts hydrate / serialize / sanitize and selection helpers\n *\n * Everything the editor offers is limited to what the field accepts (`features`): a toolbar button, a slash command, a\n * Markdown shortcut or pasted markup the field cannot hold is not offered, or is turned into what it can hold and said so.\n */\nimport * as React from \"react\";\nimport { createPortal, flushSync } from \"react-dom\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { IconArrowBarToDown, IconArrowBarToUp, IconCopy, IconGripVertical, IconPlus, IconTransform, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { useKitEnv, useKitServices, type AiPreset } from \"../../context\";\nimport { Button } from \"../../ui/button\";\nimport { Textarea } from \"../../ui/input\";\nimport { ExpandedEditorModal } from \"../../ui/expanded-editor-modal\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Tooltip } from \"../../ui/overlay\";\nimport { shortcutHintsOn } from \"../../ui/shortcut-hint\";\nimport { ALL_FEATURES, type RichTextFeature } from \"./codec\";\nimport type { KitHistoryStep } from \"../component-services\";\nimport { Island, type IslandCtx } from \"./blocks\";\nimport { CatalogComponentsProvider, InsertMenuContent, SlashMenuPanel, blockAllowed, catalogKey, noteRecent, useCatalog, type CatalogComponents, type CatalogItem } from \"./catalog\";\nimport {\n bodyCountLabel, closestBlock, countComponents, countWords, createIsland, defaultModel, editingHost, esc, hydrate, isEmptyHtml, placeCaret, rangeRect, rid, sanitize,\n serialize, textBeforeCaret, topBlock, type IslandEl, type IslandModels, type IslandKind,\n} from \"./dom\";\nimport { htmlToMarkdown, looksLikeMarkdown, markdownToHtml } from \"./markdown\";\nimport * as ops from \"./ops\";\nimport { SelectionBubble } from \"./floating\";\nimport { LinkForm, type TextLink } from \"./link-form\";\nimport { EMPTY_FMT, FormatToolbar, MARK_FEATURE, stylesFor, type Fmt, type MarkCmd } from \"./toolbar\";\n\n/* ── Prose styles for the editable surface (kit tokens only) ── */\nexport const RT_PROSE =\n \"text-kit-base leading-[1.6] text-kit-fg [&>*+*]:mt-3 \" +\n \"[&_h1]:text-[28px] [&_h1]:font-semibold [&_h1]:leading-9 [&_h1]:tracking-[-0.01em] [&_h2]:text-[22px] [&_h2]:font-semibold [&_h2]:leading-8 [&_h2]:tracking-[-0.01em] \" +\n \"[&_h3]:text-kit-lg [&_h3]:font-semibold [&_h4]:text-kit-md [&_h4]:font-semibold [&_h5]:text-kit-base [&_h5]:font-semibold [&_h6]:text-kit-sm [&_h6]:font-semibold [&_h6]:uppercase [&_h6]:tracking-wide [&_h6]:text-kit-fg-2 [&>h1]:mt-6 [&>h2]:mt-6 [&>h3]:mt-5 [&>*:first-child]:mt-0 \" +\n // a block's own list (key takeaways, V2 data-rt-isolate) is app UI, not body prose: V2 rich-text-editor.tsx skips it\n \"[&_ul:not([data-rt-isolate]_*)]:list-disc [&_ul:not([data-rt-isolate]_*)]:pl-5 [&_ol:not([data-rt-isolate]_*)]:list-decimal [&_ol:not([data-rt-isolate]_*)]:pl-5 [&_li:not([data-rt-isolate]_*)]:pl-1 [&_li+li:not([data-rt-isolate]_*)]:mt-1 [&_li:not([data-rt-isolate]_*)]:marker:text-kit-fg-3 \" +\n \"[&_blockquote]:border-l-2 [&_blockquote]:border-kit-line-strong [&_blockquote]:pl-4 [&_blockquote]:text-kit-fg-2 [&_blockquote]:italic \" +\n \"[&_a]:text-kit-accent-fg [&_a]:underline [&_a]:decoration-kit-accent-line [&_a]:underline-offset-2 \" +\n // a glossary term (`<abbr data-term title>`) reads as a dotted underline; a footnote marker as a small superscript\n \"[&_abbr]:cursor-help [&_abbr]:underline [&_abbr]:decoration-dotted [&_abbr]:underline-offset-2 [&_sup]:text-[0.7em] [&_sup]:leading-none \" +\n \"[&_code]:rounded-kit-md [&_code]:bg-kit-muted [&_code]:px-1 [&_code]:py-px [&_code]:font-kit-mono [&_code]:text-[0.9em] \" +\n \"[&_pre]:overflow-x-auto [&_pre]:whitespace-pre-wrap [&_pre]:rounded-kit-lg [&_pre]:border [&_pre]:border-kit-line [&_pre]:bg-kit-code [&_pre]:p-3 [&_pre]:font-kit-mono [&_pre]:text-kit-sm \" +\n \"[&_pre_code]:rounded-none [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-[1em] \" +\n \"[&_hr]:my-6 [&_hr]:border-kit-line \" +\n \"[&_table]:w-full [&_table]:border-collapse [&_table]:text-kit-sm [&_td]:border [&_td]:border-kit-line [&_td]:px-2.5 [&_td]:py-1.5 [&_td]:align-top [&_th]:border [&_th]:border-kit-line [&_th]:bg-kit-subtle [&_th]:px-2.5 [&_th]:py-1.5 [&_th]:text-left [&_th]:align-top [&_th]:font-medium\";\n\n/** Panel density (≈340px inspector): 13px text, smaller headings. */\nconst RT_PANEL = \"text-kit-sm leading-[1.6] [&_h1]:text-kit-xl [&_h1]:leading-7 [&_h2]:text-kit-lg [&_h2]:leading-7 [&_h3]:text-kit-md [&_h4]:text-kit-base [&_h5]:text-kit-sm [&_h6]:text-kit-xs\";\n\n/** execCommand, where the engine has it (it returns false where it does not). */\nconst exec = (cmd: string, arg?: string): boolean => {\n try {\n return typeof document.execCommand === \"function\" && document.execCommand(cmd, false, arg);\n } catch {\n return false;\n }\n};\nconst queryState = (c: string) => {\n try {\n return typeof document.queryCommandState === \"function\" && document.queryCommandState(c);\n } catch {\n return false;\n }\n};\n/** Insert HTML at the caret: the browser's own insert (undoable), else by hand. */\nfunction insertHtmlAtCaret(html: string) {\n if (exec(\"insertHTML\", html)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = sanitize(html);\n const last = tpl.content.lastChild;\n r.insertNode(tpl.content);\n if (last) {\n r.setStartAfter(last);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n }\n}\nfunction insertTextAtCaret(text: string) {\n if (exec(\"insertText\", text)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const t = document.createTextNode(text);\n r.insertNode(t);\n r.setStartAfter(t);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n}\n\n/** The slash menu at full height (header 32, list 300, footer 28, borders), the least it shrinks to, and the gap it keeps from the window's edge. */\nconst SLASH_MENU_H = 362;\nconst SLASH_MIN_H = 160;\nconst SLASH_EDGE = 8;\n\n/**\n * Where the slash menu goes, collision-aware: below the caret when the whole menu fits there, else on the side with\n * more room, and never taller than that room (its list scrolls), so the last row (More components) stays reachable in\n * a short window.\n */\nexport function slashPlacement(caret: { top: number; bottom: number }, viewportH: number): { flipUp: boolean; maxHeight: number } {\n const below = viewportH - caret.bottom - 6 - SLASH_EDGE;\n const above = caret.top - 6 - SLASH_EDGE;\n const flipUp = below < SLASH_MENU_H && above > below;\n return { flipUp, maxHeight: Math.max(SLASH_MIN_H, Math.min(SLASH_MENU_H, flipUp ? above : below)) };\n}\n\ntype IslandStep = { el: IslandEl; before: IslandModels[IslandKind]; label: string; at: number };\n/** A step the host's history holds (KitServices.historyStep); its undo and redo are the host's, while it is next. */\ntype HostStep = { label: string; step: KitHistoryStep };\ntype GutterState = { el: HTMLElement; top: number; height: number };\ntype SlashState = { rect: DOMRect; node: Text; offset: number; query: string; folder: boolean; active: number };\ntype LinkState = { rect: DOMRect; initial: TextLink; existing: HTMLAnchorElement | null };\ntype Notice = { message: string; description?: string; action?: { label: string; onClick: () => void } };\n\nexport interface RichTextEditorProps {\n value: string;\n onChange: (html: string) => void;\n readOnly?: boolean;\n placeholder?: string;\n docKey: string;\n /** what the field accepts; the editor offers nothing else (default: everything) */\n features?: readonly RichTextFeature[];\n /** a one-paragraph field: Enter starts no new block */\n single?: boolean;\n /** links may open in a new tab */\n allowNewTab?: boolean;\n /** the writing surface's id (the field label's `for`; its label is `${id}-label`) */\n id?: string;\n invalid?: boolean;\n /** panel = narrow (~340px) inspector, document = the full editor column. */\n variant?: \"panel\" | \"document\";\n /** CPO D49: the expanded editor's breadcrumb, root → this field (\"Alternating feature rows\", \"Thin walls\", \"Body\"). */\n expandCrumbs?: string[];\n /** Controlled expanded modal (a host's label-row action opens it too). */\n expandedOpen?: boolean;\n onExpandedOpenChange?: (open: boolean) => void;\n /** This editor IS the body of the expanded modal: toolbar always shown, tall writing surface. */\n inModal?: boolean;\n /** Already the full editor: no Expand button. */\n hideFullscreen?: boolean;\n /** Scroll the writing surface beyond this height (px). */\n maxHeight?: number;\n autoFocus?: boolean;\n /** Shows the toolbar Comment button. */\n onComment?: (quote: string) => void;\n /** the components this field may embed (the insert menus' More components); absent → none offered */\n components?: CatalogComponents;\n}\n\n/* ── Editor ────────────────────────────────────────────────────────── */\nexport function RichTextEditor({\n value,\n onChange,\n readOnly,\n placeholder,\n docKey,\n features = ALL_FEATURES,\n single,\n allowNewTab = true,\n id,\n invalid,\n variant = \"document\",\n expandCrumbs,\n expandedOpen,\n onExpandedOpenChange,\n inModal,\n hideFullscreen,\n maxHeight,\n autoFocus,\n onComment,\n components,\n}: RichTextEditorProps) {\n const hints = shortcutHintsOn();\n const ph = placeholder ?? (hints ? \"Type '/' for commands\" : \"Write something…\");\n const dense = variant === \"panel\";\n const ref = React.useRef<HTMLDivElement>(null);\n const wrap = React.useRef<HTMLDivElement>(null);\n const scroller = React.useRef<HTMLDivElement>(null);\n const saved = React.useRef<Range | null>(null);\n const known = React.useRef<string | null>(null);\n const pending = React.useRef<string | null>(null);\n /** a host undo just ran: its value is loaded even while the editor has focus (⌘Z here) */\n const forceLoad = React.useRef(false);\n const prevDoc = React.useRef<string | null>(null);\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const valueRef = React.useRef(value);\n valueRef.current = value;\n const services = useKitServices();\n const env = useKitEnv();\n const featureKey = features.join(\",\");\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const allows = React.useCallback((f: RichTextFeature) => features.includes(f), [featureKey]);\n\n const [empty, setEmpty] = React.useState(isEmptyHtml(value));\n const [words, setWords] = React.useState(() => countWords(value));\n const [comps, setComps] = React.useState(() => countComponents(value));\n const [fmt, setFmt] = React.useState<Fmt>(EMPTY_FMT);\n const [modalOwn, setModalOwn] = React.useState(false);\n const modalOpen = expandedOpen ?? modalOwn;\n const setModalOpen = (o: boolean) => (onExpandedOpenChange ? onExpandedOpenChange(o) : setModalOwn(o));\n const [md, setMd] = React.useState<{ text: string; original: string } | null>(null);\n const [mdConfirm, setMdConfirm] = React.useState(false);\n const [bubble, setBubble] = React.useState<DOMRect | null>(null);\n const [slash, setSlash] = React.useState<SlashState | null>(null);\n const [gutter, setGutter] = React.useState<GutterState | null>(null);\n const [blockMenu, setBlockMenu] = React.useState(false);\n const [gutterInsert, setGutterInsert] = React.useState(false);\n const gutterTarget = React.useRef<HTMLElement | null>(null);\n // D58: AI writing help follows ai.use and needs the host's AI service; without both no AI entry point is drawn.\n const canAI = env.can(\"ai.use\") && !!services.aiRewrite;\n const aiAttempt = React.useRef(0);\n const [link, setLink] = React.useState<LinkState | null>(null);\n const [drag, setDrag] = React.useState<{ from: HTMLElement; line: number | null; target: Element | null } | null>(null);\n const [focused, setFocused] = React.useState(false);\n const [menus, setMenus] = React.useState({ style: false, more: false });\n const [insertOpen, setInsertOpen] = React.useState(false);\n const inserted = React.useRef(false);\n const [islands, setIslands] = React.useState<{ id: string; el: IslandEl }[]>([]);\n const hist = React.useRef<{ past: IslandStep[]; future: IslandStep[]; textAt: number; hosts: HostStep[] }>({ past: [], future: [], textAt: 0, hosts: [] });\n const [width, setWidth] = React.useState(720);\n /* The block gutter (+ / grip) never reserves room inside the field: it floats in the space LEFT of the box when the\n host leaves ≥ 48px there (document columns), and sits in the box's padding otherwise. */\n const [gutterRoom, setGutterRoom] = React.useState(false);\n const blurTimer = React.useRef<number | undefined>(undefined);\n const [notice, setNotice] = React.useState<Notice | null>(null);\n\n const expanded = !!inModal;\n const toolbarOpen = !readOnly && (focused || menus.style || menus.more || insertOpen || expanded || !!md || !!link);\n const scrollable = !!maxHeight && !expanded;\n\n /** A refusal or a result the author must see: the host's toaster, else a line under the editor. Never silent. */\n const notify = React.useCallback(\n (message: string, opts: { description?: string; action?: Notice[\"action\"] } = {}) => {\n if (services.toast) services.toast(message, opts);\n else setNotice({ message, ...opts });\n },\n [services],\n );\n React.useEffect(() => {\n if (!notice) return;\n const t = window.setTimeout(() => setNotice(null), 8000);\n return () => window.clearTimeout(t);\n }, [notice]);\n\n /* ── islands ─────────────────────────────────────────────────────── */\n const syncIslands = React.useCallback(() => {\n const el = ref.current;\n if (!el) return setIslands((p) => (p.length ? [] : p));\n const list = Array.from(el.querySelectorAll<IslandEl>(\":scope > [data-rt-island]\"));\n const seen = new Set<string>();\n for (const x of list) {\n if (!x.__rt) {\n // a copy the browser made (drag/drop, native undo of a clone): start it fresh\n x.innerHTML = \"\";\n x.__rt = defaultModel(x.getAttribute(\"data-rt-island\") as IslandKind);\n delete x.dataset.rtId;\n }\n if (!x.dataset.rtId || seen.has(x.dataset.rtId)) x.dataset.rtId = rid(\"i\");\n seen.add(x.dataset.rtId);\n }\n setIslands((prev) => (prev.length === list.length && prev.every((p, i) => p.el === list[i]) ? prev : list.map((x) => ({ id: x.dataset.rtId!, el: x }))));\n }, []);\n\n /* ── value in / out ──────────────────────────────────────────────── */\n const load = React.useCallback(\n (html: string) => {\n const el = ref.current;\n if (!el) return;\n el.innerHTML = sanitize(html || \"\") || \"<p><br></p>\";\n hydrate(el);\n known.current = html;\n setEmpty(isEmptyHtml(html));\n setWords(countWords(html));\n setComps(countComponents(html));\n syncIslands();\n },\n [syncIslands],\n );\n\n const emit = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n syncIslands();\n const html = serialize(el);\n setEmpty(isEmptyHtml(html) && !el.querySelector(\":scope > [data-rt-island], :scope > hr\"));\n setWords(countWords(html));\n setComps(countComponents(html));\n if (html === known.current) return;\n forceLoad.current = false;\n known.current = html;\n onChangeRef.current(html);\n }, [syncIslands]);\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const docChanged = prevDoc.current !== null && prevDoc.current !== docKey;\n prevDoc.current = docKey;\n if (pending.current !== null) {\n const h = pending.current;\n pending.current = null;\n load(h);\n return;\n }\n if (forceLoad.current && value !== known.current) {\n forceLoad.current = false;\n load(value);\n return;\n }\n if (docChanged || !el.firstChild || (value !== known.current && !wrap.current?.contains(document.activeElement))) load(value);\n }, [value, docKey, md, load]);\n\n React.useEffect(() => {\n setMd(null);\n setMdConfirm(false);\n setSlash(null);\n setLink(null);\n setGutter(null);\n }, [docKey]);\n\n React.useEffect(() => {\n exec(\"defaultParagraphSeparator\", \"p\");\n if (autoFocus && ref.current && !readOnly) {\n ref.current.focus({ preventScroll: true });\n placeCaret(ref.current.lastElementChild ?? ref.current);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n const w = wrap.current;\n if (!w || typeof ResizeObserver === \"undefined\") return;\n const measureRoom = () => {\n let a = w.parentElement;\n while (a && a !== document.body) {\n const cs = getComputedStyle(a);\n if (cs.overflowX !== \"visible\" || cs.overflowY !== \"visible\") break;\n a = a.parentElement;\n }\n const left = w.getBoundingClientRect().left - (a ? a.getBoundingClientRect().left : 0);\n setGutterRoom(left >= 48);\n };\n const ro = new ResizeObserver(([e]) => {\n setWidth(Math.round(e.contentRect.width));\n measureRoom();\n });\n ro.observe(w);\n return () => ro.disconnect();\n }, []);\n\n /* the toolbar sticks below any sticky header (e.g. field tabs) in the same scroll area */\n const [stickyTop, setStickyTop] = React.useState(0);\n React.useEffect(() => {\n const w = wrap.current;\n if (!toolbarOpen || dense || !w) return;\n let sp = w.parentElement;\n while (sp && !/(auto|scroll)/.test(getComputedStyle(sp).overflowY)) sp = sp.parentElement;\n if (!sp) return setStickyTop(0);\n let top = 0;\n sp.querySelectorAll<HTMLElement>(\".sticky\").forEach((h) => {\n if (h.contains(w) || w.contains(h) || !(h.compareDocumentPosition(w) & Node.DOCUMENT_POSITION_FOLLOWING)) return;\n const cs = getComputedStyle(h);\n if (cs.position !== \"sticky\") return;\n top = Math.max(top, (parseFloat(cs.top) || 0) + h.offsetHeight);\n });\n setStickyTop(top);\n }, [toolbarOpen, dense]);\n\n // the slash menu follows the caret when anything scrolls; it closes only when the caret has left the \"/\" it was opened for\n const hasSlash = !!slash;\n React.useEffect(() => {\n if (!hasSlash) return;\n let raf = 0;\n const on = (e: Event) => {\n if (e.target instanceof Element && e.target.closest(\"[role=listbox]\")) return;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() =>\n setSlash((sl) => {\n const s = window.getSelection();\n if (!sl || !s || !s.rangeCount || s.getRangeAt(0).startContainer !== sl.node) return null;\n const rect = rangeRect(s.getRangeAt(0), sl.node.parentElement ?? ref.current);\n return rect.top === sl.rect.top && rect.left === sl.rect.left ? sl : { ...sl, rect };\n }),\n );\n };\n window.addEventListener(\"scroll\", on, true);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener(\"scroll\", on, true);\n };\n }, [hasSlash]);\n\n // keep the bubble on the selection while anything scrolls (incl. the toolbar sliding open)\n const hasBubble = !!bubble;\n React.useEffect(() => {\n if (!hasBubble) return;\n let raf = 0;\n const on = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const s = window.getSelection();\n const ok = s && s.rangeCount && !s.isCollapsed && ref.current?.contains(s.anchorNode);\n setBubble(ok ? rangeRect(s!.getRangeAt(0), ref.current) : null);\n });\n };\n window.addEventListener(\"scroll\", on, true);\n window.addEventListener(\"resize\", on);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener(\"scroll\", on, true);\n window.removeEventListener(\"resize\", on);\n };\n }, [hasBubble]);\n\n /* ── selection ───────────────────────────────────────────────────── */\n const saveSel = () => {\n const s = window.getSelection();\n if (s && s.rangeCount && ref.current?.contains(s.anchorNode)) saved.current = s.getRangeAt(0).cloneRange();\n };\n const restoreSel = () => {\n const el = ref.current;\n if (!el) return;\n const r = saved.current;\n const s = window.getSelection();\n if (r && el.contains(r.startContainer) && s) {\n (editingHost(r.startContainer) ?? el).focus({ preventScroll: true });\n s.removeAllRanges();\n s.addRange(r);\n } else {\n el.focus({ preventScroll: true });\n placeCaret(el.lastElementChild ?? el);\n }\n };\n\n const refresh = React.useCallback(() => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !el.contains(s.anchorNode)) return;\n saved.current = s.getRangeAt(0).cloneRange();\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const inIsland = !!anchorEl?.closest(\"[data-rt-island]\");\n const tb = topBlock(el, s.anchorNode);\n const r = s.getRangeAt(0);\n const hasSel = !s.isCollapsed && !!r.toString().trim();\n const next: Fmt = {\n bold: queryState(\"bold\") && !/^H[1-6]$/.test(tb?.tagName ?? \"\"),\n italic: queryState(\"italic\"),\n underline: queryState(\"underline\"),\n strike: queryState(\"strikeThrough\"),\n ul: !inIsland && tb?.tagName === \"UL\",\n ol: !inIsland && tb?.tagName === \"OL\",\n block: inIsland ? \"island\" : (tb?.tagName.toLowerCase() ?? \"p\"),\n hasSel,\n onLink: !!anchorEl?.closest(\"a\"),\n };\n setFmt((p) => (JSON.stringify(p) === JSON.stringify(next) ? p : next));\n setBubble(hasSel ? rangeRect(r, el) : null);\n el.querySelectorAll(\":scope > [data-hint]\").forEach((n) => (n !== tb || n.textContent) && n.removeAttribute(\"data-hint\"));\n if (tb && tb.tagName === \"P\" && s.isCollapsed && !tb.textContent && !tb.querySelector(\"img\") && document.activeElement === el && shortcutHintsOn()) tb.setAttribute(\"data-hint\", \"Type '/' for commands\");\n }, []);\n\n React.useEffect(() => {\n const on = () => refresh();\n document.addEventListener(\"selectionchange\", on);\n return () => document.removeEventListener(\"selectionchange\", on);\n }, [refresh]);\n\n const run = (fn: () => void) => {\n restoreSel();\n fn();\n emit();\n refresh();\n };\n\n /* ── gutter ──────────────────────────────────────────────────────── */\n const placeGutter = (b: HTMLElement | null) => {\n const sc = scroller.current;\n if (!b || !sc) return setGutter(null);\n const sr = sc.getBoundingClientRect();\n const br = b.getBoundingClientRect();\n setGutter((g) => {\n const top = br.top - sr.top + sc.scrollTop;\n return g && g.el === b && g.top === top ? g : { el: b, top, height: br.height };\n });\n };\n const currentBlock = (): HTMLElement | null => {\n const el = ref.current;\n if (!el) return null;\n const s = window.getSelection();\n return topBlock(el, s && s.rangeCount && el.contains(s.anchorNode) ? s.anchorNode : document.activeElement);\n };\n\n /* ── block operations (DOM work lives in ./ops) ─────────── */\n const deleteBlock = (b: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(b)) return;\n const next = b.nextSibling;\n b.remove();\n let filler: HTMLElement | null = null;\n if (!el.firstElementChild) {\n filler = document.createElement(\"p\");\n filler.innerHTML = \"<br>\";\n el.append(filler);\n }\n setGutter(null);\n setBlockMenu(false);\n emit();\n notify(\"Block deleted\", {\n action: {\n label: \"Undo\",\n onClick: () => {\n const root = ref.current;\n if (!root) return;\n if (filler?.isConnected && !filler.textContent) filler.remove();\n if (next && next.parentNode === root) root.insertBefore(b, next);\n else root.append(b);\n emit();\n },\n },\n });\n };\n\n const duplicateBlock = (b: HTMLElement) => {\n const c = ops.duplicateBlock(b);\n emit();\n if (gutter) placeGutter(c);\n };\n\n const moveBlock = (b: HTMLElement, dir: -1 | 1) => {\n if (!ops.moveBlock(b, dir)) return;\n emit();\n if (gutter) requestAnimationFrame(() => placeGutter(b));\n };\n\n const turnInto = (b: HTMLElement | null, tag: string) => {\n const el = ref.current;\n if (el && ops.turnInto(el, b, tag)) emit();\n };\n\n const exitIsland = (x: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(x)) return;\n const next = ops.ensureLineAfter(x);\n el.focus({ preventScroll: true });\n placeCaret(next, false);\n emit();\n };\n\n const insertBlock = (it: CatalogItem) => {\n const el = ref.current;\n if (!el || readOnly) return;\n if (it.kind === \"component\" && it.component) {\n // V2 insert: a fresh linked instance, ONE undo step\n const c = it.component;\n noteRecent(it);\n oneStep(`Insert ${c.name}`, () => {\n const isl = ops.insertIsland(el, \"component\", { ...defaultModel(\"component\"), ref: c.id, name: c.name });\n emit();\n return isl;\n });\n refresh();\n return;\n }\n if (!it.id || !blockAllowed(it.id, allows)) return;\n noteRecent(it);\n ops.insertBasic(el, it.id);\n emit();\n refresh();\n };\n\n /* ── slash menu ──────────────────────────────────────────────────── */\n const slashCat = useCatalog(slash?.query ?? \"\", allows, slash?.folder ?? false, components ?? null);\n const caretRect = () => {\n const s = window.getSelection();\n if (!s || !s.rangeCount) return null;\n return rangeRect(s.getRangeAt(0), topBlock(ref.current, s.anchorNode) ?? ref.current);\n };\n const pickSlash = (it: CatalogItem) => {\n if (it.kind === \"folder\") return setSlash((s) => s && { ...s, folder: true, active: 1 });\n if (it.kind === \"back\") return setSlash((s) => s && { ...s, folder: false, active: 0 });\n const sl = slash;\n setSlash(null);\n if (sl) {\n try {\n const r = document.createRange();\n r.setStart(sl.node, sl.offset);\n r.setEnd(sl.node, Math.min(sl.node.length, sl.offset + 1 + sl.query.length));\n r.deleteContents();\n const c = document.createRange();\n c.setStart(sl.node, Math.min(sl.offset, sl.node.length));\n c.collapse(true);\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(c);\n } catch {\n /* the text moved */\n }\n // A component is ONE step of the host's history, recorded from the body as it stands when the step starts: the\n // typed \"/query\" goes first, flushed, so an undo of the insert never brings it back as a paragraph.\n if (it.kind === \"component\") flushSync(() => emit());\n }\n insertBlock(it);\n };\n\n const toggleInlineCode = () => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !allows(\"code\")) return;\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const code = anchorEl?.closest(\"code\");\n if (code && el.contains(code) && !code.closest(\"pre\")) {\n code.replaceWith(...Array.from(code.childNodes));\n emit();\n return;\n }\n const text = s.toString();\n if (!text) return void notify(\"Select some text first\", { description: \"Or wrap words in backticks to format them as code.\" });\n insertHtmlAtCaret(`<code>${esc(text)}</code>`);\n emit();\n };\n\n /* ── keyboard ────────────────────────────────────────────────────── */\n const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (slash) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setSlash(slash.folder ? { ...slash, folder: false, active: 0 } : null);\n return;\n }\n if (catalogKey(e, slashCat.flat, slash.active, (a) => setSlash((s) => s && { ...s, active: a }), pickSlash, false)) {\n e.preventDefault();\n return;\n }\n }\n const mod = e.metaKey || e.ctrlKey;\n const k = e.key.toLowerCase();\n if (mod && !e.altKey && k === \"k\") {\n e.preventDefault();\n saveSel();\n openLink();\n return;\n }\n if (mod && !e.altKey && !e.shiftKey && k === \"e\") {\n e.preventDefault();\n toggleInlineCode();\n return;\n }\n // the browser's own mark shortcuts, only for the marks the field keeps\n if (mod && !e.altKey && !e.shiftKey && ((k === \"b\" && !allows(\"bold\")) || (k === \"i\" && !allows(\"italic\")) || (k === \"u\" && !allows(\"underline\")))) {\n e.preventDefault();\n return;\n }\n if (mod && e.altKey && /^Digit[0-6]$/.test(e.code)) {\n e.preventDefault();\n const n = Number(e.code.slice(5));\n const tag = n === 0 ? \"p\" : `h${n}`;\n if (tag === \"p\" || allows(tag as RichTextFeature)) turnInto(currentBlock(), tag);\n return;\n }\n if (e.key === \"Enter\" && !mod && !e.shiftKey) {\n // a one-paragraph field has no second block to start\n if (single) {\n e.preventDefault();\n return;\n }\n // Enter on an empty quote or heading line leaves it for a paragraph\n const cb = currentBlock();\n if (cb && /^(BLOCKQUOTE|H[1-6])$/.test(cb.tagName) && !cb.textContent?.replace(//g, \"\").trim()) {\n e.preventDefault();\n turnInto(cb, \"p\");\n return;\n }\n // Enter at the end of a quote starts a paragraph (not another quote)\n const sel = window.getSelection();\n if (cb?.tagName === \"BLOCKQUOTE\" && sel?.isCollapsed && sel.rangeCount && !cb.querySelector(\"p\")) {\n const rest = document.createRange();\n rest.selectNodeContents(cb);\n rest.setStart(sel.anchorNode!, sel.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n cb.after(p);\n placeCaret(p);\n emit();\n return;\n }\n }\n const s = window.getSelection();\n const pre = s?.anchorNode && (s.anchorNode.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode.parentElement)?.closest(\"pre\");\n if (pre && ref.current?.contains(pre)) {\n e.preventDefault();\n exec(\"insertLineBreak\");\n return;\n }\n }\n if (e.key === \"ArrowDown\" && !mod && !e.shiftKey && !single) {\n // leave a trailing heading / quote / code block / list\n const b = currentBlock();\n const s = window.getSelection();\n if (b && !b.nextElementSibling && b.tagName !== \"P\" && !b.hasAttribute(\"data-rt-island\") && s?.isCollapsed && s.rangeCount) {\n const rest = document.createRange();\n rest.selectNodeContents(b);\n rest.setStart(s.anchorNode!, s.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = ops.ensureLineAfter(b);\n placeCaret(p, false);\n emit();\n }\n }\n }\n };\n\n /** Block-level shortcuts; runs for the surface and for text inside rich blocks. */\n const onWrapKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.defaultPrevented) return;\n const mod = e.metaKey || e.ctrlKey;\n if (mod && e.key === \"Enter\" && !hideFullscreen) {\n e.preventDefault();\n setModalOpen(true);\n return;\n }\n if (md || readOnly) return;\n const t = e.target as HTMLElement;\n if (!ref.current?.contains(t) || t.tagName === \"INPUT\" || t.tagName === \"TEXTAREA\") return;\n if (undoKey(e)) return;\n if (single) return;\n if (mod && !e.shiftKey && !e.altKey && e.key.toLowerCase() === \"d\") {\n e.preventDefault();\n const b = currentBlock();\n if (b) duplicateBlock(b);\n return;\n }\n if (mod && e.shiftKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n const b = currentBlock();\n if (b) moveBlock(b, e.key === \"ArrowUp\" ? -1 : 1);\n }\n };\n\n const onInput = (e: React.FormEvent<HTMLDivElement>) => {\n if (e.target !== ref.current) return;\n const ne = e.nativeEvent as InputEvent;\n if (ne.inputType !== \"historyUndo\" && ne.inputType !== \"historyRedo\") {\n hist.current.textAt = Date.now();\n hist.current.future = [];\n }\n if (!single && ne.inputType === \"insertText\" && (ne.data === \" \" || ne.data === \"-\") && ops.liveMarkdown(ref.current!, ne.data, allows)) {\n setSlash(null);\n emit();\n return;\n }\n if (ne.inputType === \"insertText\" && ne.data === \"`\" && allows(\"code\")) ops.liveInlineCode();\n emit();\n const s = window.getSelection();\n if (!s || !s.rangeCount) return setSlash(null);\n const r = s.getRangeAt(0);\n if (!slash) {\n // \"/\" opens the menu only at the very start of a block, and only in a field that takes more than one block\n if (single || ne.inputType !== \"insertText\" || ne.data !== \"/\" || r.startContainer.nodeType !== 3) return;\n const blk = closestBlock(ref.current!, r.startContainer);\n if (!blk || textBeforeCaret(blk) !== \"/\") return;\n const rect = caretRect();\n if (rect) setSlash({ rect, node: r.startContainer as Text, offset: r.startOffset - 1, query: \"\", folder: false, active: 0 });\n return;\n }\n if (r.startContainer !== slash.node || r.startOffset <= slash.offset || slash.node.data[slash.offset] !== \"/\") return setSlash(null);\n const q = slash.node.data.slice(slash.offset + 1, r.startOffset);\n if (/\\s/.test(q) || q.length > 24) return setSlash(null);\n setSlash({ ...slash, query: q, active: slash.folder ? 1 : 0 });\n };\n\n /* ── links ───────────────────────────────────────────────────────── */\n const openLink = () => {\n if (!allows(\"link\")) return;\n restoreSel();\n const s = window.getSelection();\n const anchorEl = s?.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s?.anchorNode?.parentElement;\n const anchor = (anchorEl?.closest(\"a\") as HTMLAnchorElement | null) ?? null;\n if (!anchor && (!s || s.isCollapsed || !s.toString().trim())) {\n notify(\"Select some text first\", { description: hints ? \"Then press ⌘K to link it.\" : \"Then link it.\" });\n return;\n }\n const rect = s && s.rangeCount ? rangeRect(s.getRangeAt(0), ref.current) : ref.current!.getBoundingClientRect();\n setBubble(null);\n setLink({ rect, existing: anchor, initial: anchor ? { href: anchor.getAttribute(\"href\") ?? \"\", newTab: anchor.getAttribute(\"target\") === \"_blank\" } : { href: \"\" } });\n };\n const saveLink = (v: TextLink) => {\n const l = link;\n setLink(null);\n if (!l) return;\n if (l.existing) {\n l.existing.setAttribute(\"href\", v.href);\n if (v.newTab) l.existing.setAttribute(\"target\", \"_blank\");\n else l.existing.removeAttribute(\"target\");\n emit();\n return;\n }\n run(() => {\n const text = window.getSelection()?.toString() || v.href;\n insertHtmlAtCaret(`<a href=\"${esc(v.href).replace(/\"/g, \""\")}\"${v.newTab ? ` target=\"_blank\"` : \"\"}>${esc(text)}</a>`);\n });\n };\n\n /* ── AI rewrite of the selection (the host's service) ────────────── */\n const aiRewrite = (preset: AiPreset) => {\n const rewrite = services.aiRewrite;\n restoreSel();\n const range = saved.current?.cloneRange();\n const text = range?.toString() ?? \"\";\n if (!rewrite || !range || !text.trim()) return;\n setBubble(null);\n Promise.resolve()\n .then(() => rewrite(text, preset, aiAttempt.current++))\n .then(\n (out) => {\n const el = ref.current;\n if (!el || !el.contains(range.startContainer) || range.toString() !== text) {\n notify(\"The text changed before the rewrite came back\", { description: \"Nothing was replaced. Select it again to retry.\" });\n return;\n }\n el.focus({ preventScroll: true });\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(range);\n insertTextAtCaret(out);\n emit();\n notify(\"Rewritten with AI\", { description: hints ? \"Press ⌘Z to undo\" : undefined });\n },\n (err: unknown) => notify(\"Could not rewrite the selection\", { description: err instanceof Error ? err.message : String(err) }),\n );\n };\n\n /* ── drag to reorder via the grip ────────────────────────────────── */\n const onGripDown = (e: React.PointerEvent) => {\n if (!gutter) return;\n startDrag(gutter.el, e, () => setBlockMenu(true));\n };\n /** Drag a top-level block (the gutter grip) to a new position; a tap calls `onTap`. */\n const startDrag = (from: HTMLElement, e: React.PointerEvent, onTap?: () => void) => {\n if (readOnly || e.button !== 0) return;\n e.preventDefault();\n const start = e.clientY;\n let moved = false;\n const kids = () => Array.from(ref.current?.children ?? []);\n const move = (ev: PointerEvent) => {\n if (!moved && Math.abs(ev.clientY - start) < 4) return;\n moved = true;\n const sc = scroller.current!;\n const sr = sc.getBoundingClientRect();\n let target: Element | null = null;\n let line = 0;\n for (const k of kids()) {\n const r = k.getBoundingClientRect();\n if (ev.clientY < r.top + r.height / 2) {\n target = k;\n line = r.top - sr.top + sc.scrollTop - 4;\n break;\n }\n line = r.bottom - sr.top + sc.scrollTop + 4;\n }\n setDrag({ from, line, target });\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n if (!moved) {\n onTap?.();\n return;\n }\n setDrag((d) => {\n if (d && d.target !== d.from) {\n if (d.target) d.target.before(d.from);\n else ref.current?.append(d.from);\n setTimeout(emit, 0);\n }\n return null;\n });\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n /* ── pasted and converted markup keeps to the field's rules ──────── */\n const conform = (html: string): string => {\n const r = ops.restrictHtml(html, allows);\n if (r.dropped.length) notify(`This field keeps no ${r.dropped.join(\" or \")}`, { description: \"They were left out; the text around them was kept.\" });\n return r.html;\n };\n\n /* ── Markdown mode ───────────────────────────────────────────────── */\n const toggleMarkdown = () => {\n if (!md) {\n const html = ref.current ? serialize(ref.current) : value;\n const text = htmlToMarkdown(html);\n setMd({ text, original: text });\n setSlash(null);\n setGutter(null);\n setBubble(null);\n setLink(null);\n return;\n }\n if (md.text === md.original) {\n setMd(null);\n setMdConfirm(false);\n return;\n }\n setMdConfirm(true);\n };\n const convertMarkdown = () => {\n if (!md) return;\n let html: string;\n try {\n html = conform(markdownToHtml(md.text));\n } catch (err) {\n notify(\"Could not convert this Markdown\", { description: `${err instanceof Error ? err.message : String(err)}. Your rich text is unchanged.` });\n return;\n }\n pending.current = html;\n known.current = html;\n onChangeRef.current(html);\n setMd(null);\n setMdConfirm(false);\n };\n\n /* ── One undo history (CPO D54): typing is the browser's own undo; an island write (an image's address or alt text)\n is a step on this stack. ⌘Z takes whichever happened last. ── */\n /** A host step's undo or redo; its value then loads even here, with the caret in the editor. */\n const runHost = (run: () => true | string): true | string => {\n forceLoad.current = true;\n const r = run();\n if (r !== true) forceLoad.current = false;\n return r;\n };\n /**\n * This body's host step that is the host's next undo (or redo) NOW. The host's toolbar moves these steps too: after\n * its Undo then Redo, the step is the latest change again, so ⌘Z here undoes it. Any later change in this body is a\n * host step of its own (the body's value is the host's), so a host step that is next is the latest change here.\n */\n const hostNext = (way: \"undo\" | \"redo\"): HostStep | null => {\n const hs = hist.current.hosts;\n for (let i = hs.length - 1; i >= 0; i--) if (hs[i].step.next() === way) return hs[i];\n return null;\n };\n const islandUndo = (): boolean => {\n const host = hostNext(\"undo\");\n if (host) {\n const r = runHost(host.step.undo);\n if (r !== true) notify(\"Nothing was undone\", { description: r });\n return true;\n }\n const h = hist.current;\n // a step whose island is gone has nothing to undo\n while (h.past.length && !h.past[h.past.length - 1].el.isConnected) h.past.pop();\n const step = h.past[h.past.length - 1];\n if (!step || step.at < h.textAt) return false;\n if (!step.el.__rtSet) return false;\n h.past.pop();\n h.future.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n const islandRedo = (): boolean => {\n const host = hostNext(\"redo\");\n if (host) {\n const r = runHost(host.step.redo);\n if (r !== true) notify(\"Nothing was redone\", { description: r });\n return true;\n }\n const h = hist.current;\n const step = h.future.pop();\n if (!step || !step.el.isConnected || !step.el.__rtSet) return false;\n h.past.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n /**\n * One action as ONE undo step (a separate copy, \"use shared version again\", a component inserted): in the host's\n * history when it keeps one (KitServices.historyStep: its toolbar Undo, an Undo toast and ⌘Z here are the same\n * undo), else in this editor's own (`before`: the model the island had; an insert has none, and stays as undoable\n * as any block inserted here). `write` makes the change and answers the island it changed. Answers its undo.\n */\n const oneStep = (label: string, write: () => IslandEl | null, before?: IslandModels[IslandKind]): (() => true | string) => {\n const h = hist.current;\n const made: { el: IslandEl | null } = { el: null };\n const historyStep = services.historyStep;\n const step = historyStep\n ? historyStep(() => {\n made.el = write();\n })\n : ((made.el = write()), null);\n const el = made.el;\n if (step) {\n h.hosts = [...h.hosts, { label, step }].slice(-100);\n return () => runHost(step.undo);\n }\n if (!el || !before) return () => \"This change has no undo step here.\";\n const s: IslandStep = { el, before, label, at: Date.now() };\n h.past = [...h.past, s].slice(-100);\n h.future = [];\n return () => {\n if (!h.past.includes(s)) return \"It was undone already.\";\n if (h.past[h.past.length - 1] !== s || s.at < h.textAt) return \"Changes made after it come first. Press ⌘Z to undo them.\";\n return islandUndo() ? true : \"The block was removed, so there is nothing to undo.\";\n };\n };\n const record = (el: IslandEl, before: IslandModels[IslandKind], label: string, coalesce?: boolean) => {\n const h = hist.current;\n const now = Date.now();\n const top = h.past[h.past.length - 1];\n // typing in one field coalesces (~500ms), unless the text was edited in between\n if (coalesce && top && top.el === el && top.label === label && now - top.at < 500 && top.at > h.textAt) top.at = now;\n else h.past = [...h.past, { el, before, label, at: now }].slice(-100);\n h.future = [];\n };\n const undoKey = (e: React.KeyboardEvent): boolean => {\n const mod = e.metaKey || e.ctrlKey;\n if (!mod || e.altKey || e.key.toLowerCase() !== \"z\") return false;\n if (e.shiftKey) {\n if (!islandRedo()) return false;\n e.preventDefault();\n return true;\n }\n if (islandUndo()) {\n e.preventDefault();\n return true;\n }\n if (!hist.current.past.length || !ref.current) return false;\n e.preventDefault();\n const before = ref.current.innerHTML;\n exec(\"undo\");\n if (ref.current.innerHTML === before) {\n hist.current.textAt = 0;\n islandUndo();\n }\n return true;\n };\n\n /* ── API for islands (stable) ────────────────────────────────────── */\n const api = React.useRef({ emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo });\n api.current = { emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo };\n const islandCtx = React.useMemo<IslandCtx>(\n () => ({\n readOnly,\n dense,\n emit: () => api.current.emit(),\n remove: (x) => api.current.deleteBlock(x),\n exit: (x) => api.current.exitIsland(x),\n record: (x, before, label, coalesce) => api.current.record(x, before, label, coalesce),\n step: (label, write, before) => api.current.oneStep(label, write, before),\n notify: (message, description) => api.current.notify(message, { description }),\n duplicate: (x) => api.current.duplicateBlock(x),\n move: (x, dir) => api.current.moveBlock(x, dir),\n undo: () => api.current.islandUndo(),\n redo: () => api.current.islandRedo(),\n }),\n [readOnly, dense],\n );\n\n const commentSel = onComment\n ? () => {\n restoreSel();\n const q = window.getSelection()?.toString().trim();\n if (q) onComment(q);\n }\n : undefined;\n const onMark = (cmd: MarkCmd) => allows(MARK_FEATURE[cmd]) && run(() => exec(cmd));\n const onStyle = (tag: string) => {\n restoreSel();\n turnInto(currentBlock(), tag);\n refresh();\n };\n\n /* ── render ──────────────────────────────────────────────────────── */\n const { flipUp, maxHeight: slashMaxH } = slash ? slashPlacement(slash.rect, window.innerHeight) : { flipUp: false, maxHeight: SLASH_MENU_H };\n const gBlock = gutter?.el;\n const gIsText = !!gBlock && !gBlock.hasAttribute(\"data-rt-island\") && gBlock.tagName !== \"HR\";\n const btn = dense ? \"size-5 [&_svg]:size-3.5\" : \"size-[22px] [&_svg]:size-3.5\";\n /* outside: + and grip float left of the box · inset: a slim grip sits in the 16px padding (insert via / or the\n toolbar) · none: compact inspector fields and one-paragraph fields */\n const gutterMode: \"outside\" | \"inset\" | \"none\" = readOnly || dense || single ? \"none\" : gutterRoom ? \"outside\" : \"inset\";\n const showGutter = gutterMode !== \"none\";\n const minH = expanded ? \"min-h-[60vh]\" : single ? \"min-h-9\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\";\n const turnStyles = stylesFor(allows).filter((s) => [\"p\", \"h1\", \"h2\", \"h3\", \"blockquote\"].includes(s.tag));\n\n return (\n <CatalogComponentsProvider value={components ?? null}>\n <div\n ref={wrap}\n data-rt-editor=\"\"\n className={cn(\n \"relative rounded-kit-lg border transition-colors duration-150 [--rt-toolbar-h:2rem] pointer-coarse:[--rt-toolbar-h:2.75rem]\",\n /* the expanded modal is raised: the editor sits level with it, never below (D56) */\n expanded ? \"bg-[var(--kit-surface-raised)]\" : \"bg-kit-surface\",\n invalid ? \"border-[var(--kit-field-invalid)]\" : toolbarOpen ? \"border-kit-line-strong\" : \"border-kit-line\",\n )}\n /* what the sticky toolbar covers at the top of the scroll area */\n style={{ \"--rt-sticky-top\": toolbarOpen && !dense ? `calc(${stickyTop}px + var(--rt-toolbar-h))` : \"var(--kit-sticky-top, 0px)\" } as React.CSSProperties}\n onMouseLeave={() => !blockMenu && !gutterInsert && !drag && setGutter(null)}\n onKeyDown={onWrapKeyDown}\n onFocus={() => {\n window.clearTimeout(blurTimer.current);\n setFocused(true);\n }}\n onBlur={() => {\n window.clearTimeout(blurTimer.current);\n blurTimer.current = window.setTimeout(() => {\n const a = document.activeElement;\n if (wrap.current?.contains(a) || a?.closest(\"[role=menu],[role=dialog],[role=listbox],[data-floating-layer]\")) return;\n setFocused(false);\n setBubble(null);\n ref.current?.querySelectorAll(\"[data-hint]\").forEach((n) => n.removeAttribute(\"data-hint\"));\n if (valueRef.current !== known.current && !md) load(valueRef.current);\n }, 400);\n }}\n >\n {readOnly ? null : (\n <FormatToolbar\n open={toolbarOpen}\n sticky={!dense}\n stickyTop={stickyTop}\n width={width}\n dense={dense}\n fmt={fmt}\n md={!!md}\n allows={allows}\n hideFullscreen={hideFullscreen}\n insertOpen={insertOpen}\n setInsertOpen={(o) => {\n if (o) inserted.current = false;\n setInsertOpen(o);\n }}\n onMenuOpen={(name, o) => setMenus((m) => ({ ...m, [name]: o }))}\n onStyle={onStyle}\n onMark={onMark}\n onList={(kind) =>\n allows(kind) &&\n run(() => {\n // Chrome nests the list inside a heading/quote (<h2><ul>…) — turn the line into a paragraph first.\n const b = currentBlock();\n if (b && /^(H[1-6]|BLOCKQUOTE)$/.test(b.tagName)) turnInto(b, \"p\");\n exec(kind === \"ul\" ? \"insertUnorderedList\" : \"insertOrderedList\");\n // …and it can still leave <p><ul>…</ul></p>; lift the list out of any text block.\n ref.current?.querySelectorAll(\":is(p,h1,h2,h3,h4,h5,h6,blockquote) > :is(ul,ol)\").forEach((list) => {\n const host = list.parentElement!;\n host.replaceWith(...Array.from(host.childNodes).filter((n) => n.nodeType === 1 || n.textContent?.trim()));\n });\n })\n }\n onLink={openLink}\n onClear={() =>\n run(() => {\n exec(\"removeFormat\");\n exec(\"unlink\");\n })\n }\n onComment={commentSel}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onCodeBlock={() => {\n restoreSel();\n if (allows(\"pre\")) turnInto(currentBlock(), \"pre\");\n }}\n onInsert={(it) => {\n inserted.current = true;\n restoreSel();\n insertBlock(it);\n setInsertOpen(false);\n }}\n keepFocusOnInsertClose={() => inserted.current}\n onFullscreen={() => setModalOpen(true)}\n onMarkdown={toggleMarkdown}\n saveSel={saveSel}\n />\n )}\n\n {md ? (\n <div className=\"px-3 pb-2.5 pt-2.5\">\n <Textarea\n aria-label=\"Field content as Markdown\"\n spellCheck={false}\n value={md.text}\n readOnly={readOnly}\n onChange={(e) => {\n setMd({ ...md, text: e.target.value });\n setMdConfirm(false);\n }}\n className={cn(\"font-kit-mono text-kit-xs leading-5\", expanded ? \"min-h-[60vh]\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\")}\n style={scrollable ? { maxHeight } : undefined}\n />\n <p className=\"mt-1.5 text-kit-2xs text-kit-fg-3\">Markdown. Switching back converts it to blocks.</p>\n <AnimatePresence initial={false}>\n {mdConfirm ? (\n <motion.div\n key=\"confirm\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 4 }}\n transition={{ duration: 0.15 }}\n role=\"alertdialog\"\n aria-label=\"Convert edited Markdown?\"\n className=\"mt-2 flex flex-wrap items-center gap-2 rounded-kit-lg border border-kit-line bg-kit-subtle px-3 py-2\"\n >\n <span className=\"flex-1 text-kit-sm font-medium text-kit-fg\">Convert edited Markdown?</span>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setMdConfirm(false)}>\n Keep editing Markdown\n </Button>\n <Button size=\"xs\" variant=\"primary\" autoFocus onClick={convertMarkdown}>\n Convert to rich text\n </Button>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n ) : (\n <div\n ref={scroller}\n className={cn(\"relative\", scrollable && \"overflow-y-auto\")}\n style={scrollable ? { maxHeight } : undefined}\n onMouseMove={(e) => {\n if (drag || blockMenu || gutterInsert || !showGutter) return;\n const t = e.target as HTMLElement;\n if (t.closest(\"[data-rt-gutter]\")) return;\n placeGutter(topBlock(ref.current, t));\n }}\n >\n <div\n ref={ref}\n id={inModal ? undefined : id}\n role=\"textbox\"\n aria-multiline={!single}\n aria-labelledby={!inModal && id ? `${id}-label` : undefined}\n aria-label={inModal || !id ? (expandCrumbs?.[expandCrumbs.length - 1] ?? \"Rich text\") : undefined}\n aria-placeholder={ph}\n aria-readonly={readOnly || undefined}\n aria-invalid={invalid || undefined}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n spellCheck\n tabIndex={readOnly ? 0 : undefined}\n onInput={onInput}\n onKeyDown={onKeyDown}\n onKeyUp={refresh}\n onMouseUp={refresh}\n onPaste={(e) => {\n if (readOnly) return;\n const files = Array.from(e.clipboardData.files).filter((f) => f.type.startsWith(\"image/\"));\n if (files.length) {\n e.preventDefault();\n notify(allows(\"image\") ? \"Add images from the media library\" : \"This field keeps no images\", {\n description: allows(\"image\") ? \"A pasted file has no address the page can show it from. Use Insert › Image.\" : undefined,\n });\n return;\n }\n const text = e.clipboardData.getData(\"text/plain\");\n e.preventDefault();\n if (!text) return;\n if (single || (!/\\n/.test(text.trim()) && !looksLikeMarkdown(text))) {\n insertTextAtCaret(single ? text.replace(/\\s*\\n\\s*/g, \" \") : text);\n emit();\n return;\n }\n let html: string;\n try {\n html = markdownToHtml(text);\n } catch {\n html = text.split(/\\n{2,}/).map((p) => `<p>${esc(p.trim()).replace(/\\n/g, \"<br>\")}</p>`).join(\"\");\n }\n insertHtmlAtCaret(conform(html));\n if (ref.current) hydrate(ref.current);\n emit();\n }}\n onDragOver={(e) => {\n if (e.dataTransfer.types.includes(\"application/x-bcms-asset\") && allows(\"image\")) e.preventDefault();\n }}\n onDrop={(e) => {\n const asset = e.dataTransfer.getData(\"application/x-bcms-asset\");\n if (!asset || readOnly || !allows(\"image\")) return;\n e.preventDefault();\n try {\n const a = JSON.parse(asset) as { url: string; alt?: string; name: string };\n const b = topBlock(ref.current, e.target as Node);\n const isl = createIsland(\"image\", defaultModel(\"image\", { src: a.url, alt: a.alt ?? \"\" }));\n if (b) b.after(isl);\n else ref.current?.append(isl);\n ops.ensureLineAfter(isl);\n emit();\n } catch {\n notify(\"That drop is not an image from the media library\");\n }\n }}\n className={cn(\n RT_PROSE,\n dense && RT_PANEL,\n \"peer relative outline-none [&_*]:outline-none\",\n \"[&>p[data-hint]]:before:pointer-events-none [&>p[data-hint]]:before:float-left [&>p[data-hint]]:before:h-0 [&>p[data-hint]]:before:text-kit-fg-4 [&>p[data-hint]]:before:content-[attr(data-hint)]\",\n dense ? \"px-2.5 py-2\" : \"px-4 py-3.5\",\n minH,\n )}\n />\n {empty ? (\n <div aria-hidden className={cn(\"pointer-events-none absolute text-kit-fg-4 peer-focus:hidden\", dense ? \"left-2.5 top-2 text-kit-sm\" : \"left-4 top-3.5 text-kit-base\")}>\n {ph}\n </div>\n ) : null}\n\n {/* Block gutter (+ / grip) */}\n {gutter && showGutter ? (\n <div\n data-rt-gutter=\"\"\n /* z-3: under the sticky toolbar (z-4), so a tall block's grip never paints over it */\n className={cn(\"absolute z-[3] flex items-start\", gutterMode === \"outside\" ? \"-left-12 pr-1\" : \"left-0\")}\n style={{ top: gutter.top + Math.max(-2, Math.min(4, gutter.height / 2 - 12)) }}\n >\n {gutterMode === \"outside\" ? (\n <Popover\n open={gutterInsert}\n onOpenChange={(o) => {\n if (o) {\n gutterTarget.current = gutter.el;\n inserted.current = false;\n }\n setGutterInsert(o);\n }}\n >\n <Tooltip content=\"Add a block below\" disabled={gutterInsert}>\n <PopoverTrigger\n aria-label=\"Add a block below\"\n className={cn(\"flex items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover data-[popup-open]:text-kit-fg\", btn)}\n >\n <IconPlus stroke={1.5} aria-hidden />\n </PopoverTrigger>\n </Tooltip>\n {gutterInsert ? (\n <InsertMenuContent\n side=\"bottom\"\n align=\"start\"\n allows={allows}\n keepFocusOnClose={() => inserted.current}\n onInsert={(it) => {\n const b = gutterTarget.current;\n const el = ref.current;\n inserted.current = true;\n setGutterInsert(false);\n if (!b || !el || !el.contains(b)) return;\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n b.after(p);\n el.focus({ preventScroll: true });\n placeCaret(p);\n insertBlock(it);\n }}\n />\n ) : null}\n </Popover>\n ) : null}\n <Menu open={blockMenu} onOpenChange={setBlockMenu}>\n <Tooltip content=\"Drag to move, click for options\" disabled={blockMenu || !!drag}>\n <MenuTrigger\n aria-label=\"Block options\"\n onPointerDown={onGripDown}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setBlockMenu(true);\n }\n }}\n className={cn(\n \"flex cursor-grab items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg active:cursor-grabbing\",\n gutterMode === \"inset\" ? \"h-[22px] w-4 rounded-kit-sm [&_svg]:size-3.5\" : btn,\n (blockMenu || drag) && \"bg-kit-hover text-kit-fg\",\n )}\n >\n <IconGripVertical stroke={1.5} aria-hidden />\n </MenuTrigger>\n </Tooltip>\n <MenuContent className=\"w-56\" align=\"start\" finalFocus={false}>\n {turnStyles.length > 1 ? (\n <MenuSub>\n <MenuSubTrigger icon={<IconTransform stroke={1.5} />} disabled={!gIsText}>\n Turn into\n </MenuSubTrigger>\n <MenuSubContent className=\"w-48\">\n {turnStyles.map((t) => (\n <MenuItem key={t.tag} icon={t.icon} onClick={() => turnInto(gBlock ?? null, t.tag)}>\n {t.label}\n </MenuItem>\n ))}\n </MenuSubContent>\n </MenuSub>\n ) : null}\n <MenuItem icon={<IconCopy stroke={1.5} />} shortcut=\"⌘D\" onClick={() => gBlock && duplicateBlock(gBlock)}>\n Duplicate\n </MenuItem>\n <MenuItem icon={<IconArrowBarToUp stroke={1.5} />} shortcut=\"⌘⇧↑\" disabled={!gBlock?.previousElementSibling} onClick={() => gBlock && moveBlock(gBlock, -1)}>\n Move up\n </MenuItem>\n <MenuItem icon={<IconArrowBarToDown stroke={1.5} />} shortcut=\"⌘⇧↓\" disabled={!gBlock?.nextElementSibling} onClick={() => gBlock && moveBlock(gBlock, 1)}>\n Move down\n </MenuItem>\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} onClick={() => gBlock && deleteBlock(gBlock)}>\n Delete\n </MenuItem>\n </MenuContent>\n </Menu>\n </div>\n ) : null}\n {drag?.line != null ? <div className=\"pointer-events-none absolute inset-x-3 z-[6] h-0.5 rounded-full bg-kit-info\" style={{ top: drag.line }} /> : null}\n\n {/* Rich blocks render into their contenteditable=false hosts */}\n {islands.map(({ id: key, el }) => createPortal(<Island el={el} ctx={islandCtx} />, el, key))}\n </div>\n )}\n\n {/* Footer meta, and any refusal said in place when the host has no toaster */}\n <div className=\"flex min-h-7 items-center justify-end gap-3 rounded-b-kit-lg border-t border-kit-line-subtle px-3 text-kit-2xs text-kit-fg-3\">\n {/* V2 says these in a toast; with no toaster the refusal is said here, and the region exists only while it has one */}\n {notice ? (\n <span role=\"status\" aria-live=\"polite\" className=\"mr-auto min-w-0 truncate text-kit-fg-2\">\n {notice.message}\n {notice.description ? ` ${notice.description}` : \"\"}\n {notice.action ? (\n <button\n type=\"button\"\n className=\"ml-1.5 font-medium text-kit-fg underline underline-offset-2\"\n onClick={() => {\n notice.action!.onClick();\n setNotice(null);\n }}\n >\n {notice.action.label}\n </button>\n ) : null}\n </span>\n ) : null}\n <span className=\"shrink-0 tabular-nums\">\n {words.toLocaleString(\"en-US\")} {words === 1 ? \"word\" : \"words\"}\n {comps ? ` · ${comps} ${comps === 1 ? \"component\" : \"components\"}` : \"\"} · {Math.max(1, Math.round(words / 220))} min read\n </span>\n </div>\n\n {/* Bubble toolbar on selection: a toolbar menu owns the moment, so the bubble steps aside while one is open */}\n {bubble && !readOnly && !slash && !link && !md && !menus.style && !menus.more && !insertOpen ? (\n <SelectionBubble\n rect={bubble}\n avoid={toolbarOpen ? wrap.current?.querySelector<HTMLElement>('[role=\"toolbar\"][aria-label=\"Text formatting\"]')?.getBoundingClientRect() : null}\n fmt={fmt}\n allows={allows}\n saveSel={saveSel}\n onAi={canAI ? aiRewrite : undefined}\n onStyle={onStyle}\n onMark={onMark}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onLink={openLink}\n onComment={commentSel}\n />\n ) : null}\n\n {/* Slash menu (opens only at the start of a block; never takes focus) */}\n {slash && !md\n ? createPortal(\n <>\n <div data-floating-layer=\"\" className=\"pointer-events-auto fixed inset-0 z-[84]\" onMouseDown={() => setSlash(null)} />\n <motion.div\n initial={{ opacity: 0, y: flipUp ? -4 : 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.14 }}\n style={{\n left: Math.min(window.innerWidth - 330, Math.max(8, slash.rect.left)),\n ...(flipUp ? { bottom: window.innerHeight - slash.rect.top + 6 } : { top: slash.rect.bottom + 6 }),\n }}\n data-floating-layer=\"\"\n className=\"pointer-events-auto fixed z-[85]\"\n >\n <SlashMenuPanel query={slash.query} folder={slash.folder} active={slash.active} allows={allows} setActive={(a) => setSlash((s) => s && { ...s, active: a })} onPick={pickSlash} maxHeight={slashMaxH} />\n </motion.div>\n </>,\n document.body,\n )\n : null}\n\n {/* Link popover anchored to the selection */}\n <Popover open={!!link} onOpenChange={(o) => !o && setLink(null)}>\n <PopoverAnchor\n render={<span className=\"pointer-events-none fixed\" style={link ? { top: link.rect.bottom, left: link.rect.left, width: Math.max(1, link.rect.width), height: 1 } : { top: 0, left: 0 }} />}\n />\n <PopoverContent className=\"w-[340px] rounded-kit-lg p-3\" finalFocus={false}>\n {link ? (\n <LinkForm\n initial={link.initial}\n allowNewTab={allowNewTab}\n onSave={saveLink}\n onCancel={() => setLink(null)}\n onDetach={\n link.existing\n ? () => {\n const a = link.existing!;\n a.replaceWith(...Array.from(a.childNodes));\n setLink(null);\n emit();\n }\n : undefined\n }\n />\n ) : null}\n </PopoverContent>\n </Popover>\n {!hideFullscreen ? (\n <ExpandedEditorModal open={modalOpen} onOpenChange={setModalOpen} crumbs={expandCrumbs?.length ? expandCrumbs : [\"Text\"]} returnFocus={() => ref.current} meta={bodyCountLabel(value)}>\n {modalOpen ? (\n <RichTextEditor\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n docKey={`${docKey}:expanded`}\n features={features}\n single={single}\n allowNewTab={allowNewTab}\n expandCrumbs={expandCrumbs}\n variant=\"document\"\n hideFullscreen\n inModal\n autoFocus\n onComment={onComment}\n components={components}\n />\n ) : null}\n </ExpandedEditorModal>\n ) : null}\n </div>\n </CatalogComponentsProvider>\n );\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AiPreset } from "../../context";
|
|
2
|
+
import type { RichTextFeature } from "./codec";
|
|
3
|
+
import { type Fmt, type MarkCmd } from "./toolbar";
|
|
4
|
+
/** The bubble's rewrite directions (V2: improve, shorter, punchier, grammar), as the host service's presets. */
|
|
5
|
+
export declare const BUBBLE_AI: {
|
|
6
|
+
id: AiPreset;
|
|
7
|
+
label: string;
|
|
8
|
+
}[];
|
|
9
|
+
export declare function SelectionBubble({ rect, fmt, allows, saveSel, onAi, onStyle, onMark, onInlineCode, onLink, onComment, avoid, }: {
|
|
10
|
+
rect: DOMRect;
|
|
11
|
+
/** The editor's own toolbar row (when it is open): the bubble never sits on top of it. */
|
|
12
|
+
avoid?: DOMRect | null;
|
|
13
|
+
fmt: Fmt;
|
|
14
|
+
allows: (f: RichTextFeature) => boolean;
|
|
15
|
+
saveSel: () => void;
|
|
16
|
+
/** Absent when the person has no AI (D58: ai.use) or the host has no AI service: the AI menu and its divider are not drawn. */
|
|
17
|
+
onAi?: (preset: AiPreset) => void;
|
|
18
|
+
onStyle: (tag: string) => void;
|
|
19
|
+
onMark: (cmd: MarkCmd) => void;
|
|
20
|
+
onInlineCode: () => void;
|
|
21
|
+
onLink: () => void;
|
|
22
|
+
onComment?: () => void;
|
|
23
|
+
}): import("react").ReactPortal;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Sparkle } from "../../ui/button.js";
|
|
2
|
+
import { Menu, MenuContent, MenuItem, MenuTrigger } from "../../ui/overlay.js";
|
|
3
|
+
import { StyleMenu, ToolButton, stylesFor } from "./toolbar.js";
|
|
4
|
+
import { IconBold, IconCode, IconItalic, IconLink, IconMessage, IconStrikethrough, IconUnderline } from "@tabler/icons-react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { motion } from "framer-motion";
|
|
7
|
+
import { createPortal } from "react-dom";
|
|
8
|
+
//#region src/kit/controls/rich-text/floating.tsx
|
|
9
|
+
/**
|
|
10
|
+
* RICH TEXT · the selection bubble: AI rewrite, style, marks, link (V2 HEAD controls/rich-text/floating.tsx).
|
|
11
|
+
* V2's inline "Ask AI" prompt took free text; the host's AI service rewrites by preset only, so it is not drawn.
|
|
12
|
+
*/
|
|
13
|
+
/** The bubble's rewrite directions (V2: improve, shorter, punchier, grammar), as the host service's presets. */
|
|
14
|
+
var BUBBLE_AI = [
|
|
15
|
+
{
|
|
16
|
+
id: "improve",
|
|
17
|
+
label: "Improve writing"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "shorter",
|
|
21
|
+
label: "Make shorter"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "simplify",
|
|
25
|
+
label: "Simplify"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "grammar",
|
|
29
|
+
label: "Fix spelling and grammar"
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
function SelectionBubble({ rect, fmt, allows, saveSel, onAi, onStyle, onMark, onInlineCode, onLink, onComment, avoid }) {
|
|
33
|
+
const above = rect.top - 44;
|
|
34
|
+
const top = above < 8 || !!avoid && above < avoid.bottom + 4 && above + 36 > avoid.top ? rect.bottom + 8 : above;
|
|
35
|
+
const styles = stylesFor(allows);
|
|
36
|
+
return createPortal(/* @__PURE__ */ jsxs(motion.div, {
|
|
37
|
+
initial: {
|
|
38
|
+
opacity: 0,
|
|
39
|
+
y: 4
|
|
40
|
+
},
|
|
41
|
+
animate: {
|
|
42
|
+
opacity: 1,
|
|
43
|
+
y: 0
|
|
44
|
+
},
|
|
45
|
+
transition: { duration: .14 },
|
|
46
|
+
onMouseDown: (e) => {
|
|
47
|
+
if (!e.target.closest("button")) e.preventDefault();
|
|
48
|
+
},
|
|
49
|
+
style: {
|
|
50
|
+
top,
|
|
51
|
+
left: Math.min(window.innerWidth - 400, Math.max(8, rect.left + rect.width / 2 - 190))
|
|
52
|
+
},
|
|
53
|
+
"data-floating-layer": "",
|
|
54
|
+
"data-kit-scope": "",
|
|
55
|
+
className: "pointer-events-auto fixed z-[85] flex h-9 items-center gap-0.5 rounded-kit-lg border border-kit-line bg-kit-surface px-1 text-kit-fg shadow-kit-sm [.dark_&]:border-kit-line-strong [.dark_&]:bg-[#252528]",
|
|
56
|
+
role: "toolbar",
|
|
57
|
+
"aria-label": "Selection formatting",
|
|
58
|
+
children: [
|
|
59
|
+
onAi ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsxs(MenuTrigger, {
|
|
60
|
+
onMouseDown: (e) => {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
saveSel();
|
|
63
|
+
},
|
|
64
|
+
className: "flex h-7 items-center gap-1.5 rounded-kit-md px-2 text-kit-sm text-kit-fg hover:bg-kit-hover data-[popup-open]:bg-kit-hover",
|
|
65
|
+
children: [/* @__PURE__ */ jsx(Sparkle, { size: 14 }), " Improve writing"]
|
|
66
|
+
}), /* @__PURE__ */ jsx(MenuContent, {
|
|
67
|
+
className: "w-52",
|
|
68
|
+
finalFocus: false,
|
|
69
|
+
children: BUBBLE_AI.map((p) => /* @__PURE__ */ jsx(MenuItem, {
|
|
70
|
+
icon: /* @__PURE__ */ jsx(Sparkle, { size: 16 }),
|
|
71
|
+
onClick: () => onAi(p.id),
|
|
72
|
+
children: p.label
|
|
73
|
+
}, p.id))
|
|
74
|
+
})] }), /* @__PURE__ */ jsx("span", {
|
|
75
|
+
"aria-hidden": true,
|
|
76
|
+
className: "mx-0.5 h-4 w-px bg-kit-line"
|
|
77
|
+
})] }) : null,
|
|
78
|
+
fmt.block !== "island" && styles.length > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(StyleMenu, {
|
|
79
|
+
block: fmt.block,
|
|
80
|
+
styles,
|
|
81
|
+
onPick: onStyle
|
|
82
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
83
|
+
"aria-hidden": true,
|
|
84
|
+
className: "mx-0.5 h-4 w-px bg-kit-line"
|
|
85
|
+
})] }) : null,
|
|
86
|
+
allows("bold") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
87
|
+
label: "Bold",
|
|
88
|
+
icon: /* @__PURE__ */ jsx(IconBold, { stroke: 1.5 }),
|
|
89
|
+
shortcut: "⌘B",
|
|
90
|
+
active: fmt.bold,
|
|
91
|
+
onClick: () => onMark("bold")
|
|
92
|
+
}) : null,
|
|
93
|
+
allows("italic") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
94
|
+
label: "Italic",
|
|
95
|
+
icon: /* @__PURE__ */ jsx(IconItalic, { stroke: 1.5 }),
|
|
96
|
+
shortcut: "⌘I",
|
|
97
|
+
active: fmt.italic,
|
|
98
|
+
onClick: () => onMark("italic")
|
|
99
|
+
}) : null,
|
|
100
|
+
allows("underline") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
101
|
+
label: "Underline",
|
|
102
|
+
icon: /* @__PURE__ */ jsx(IconUnderline, { stroke: 1.5 }),
|
|
103
|
+
shortcut: "⌘U",
|
|
104
|
+
active: fmt.underline,
|
|
105
|
+
onClick: () => onMark("underline")
|
|
106
|
+
}) : null,
|
|
107
|
+
allows("strike") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
108
|
+
label: "Strikethrough",
|
|
109
|
+
icon: /* @__PURE__ */ jsx(IconStrikethrough, { stroke: 1.5 }),
|
|
110
|
+
active: fmt.strike,
|
|
111
|
+
onClick: () => onMark("strikeThrough")
|
|
112
|
+
}) : null,
|
|
113
|
+
allows("code") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
114
|
+
label: "Inline code",
|
|
115
|
+
icon: /* @__PURE__ */ jsx(IconCode, { stroke: 1.5 }),
|
|
116
|
+
shortcut: "⌘E",
|
|
117
|
+
onClick: onInlineCode
|
|
118
|
+
}) : null,
|
|
119
|
+
allows("link") ? /* @__PURE__ */ jsx(ToolButton, {
|
|
120
|
+
label: "Link",
|
|
121
|
+
icon: /* @__PURE__ */ jsx(IconLink, { stroke: 1.5 }),
|
|
122
|
+
shortcut: "⌘K",
|
|
123
|
+
active: fmt.onLink,
|
|
124
|
+
onClick: onLink
|
|
125
|
+
}) : null,
|
|
126
|
+
onComment ? /* @__PURE__ */ jsx(ToolButton, {
|
|
127
|
+
label: "Comment",
|
|
128
|
+
icon: /* @__PURE__ */ jsx(IconMessage, { stroke: 1.5 }),
|
|
129
|
+
onClick: onComment
|
|
130
|
+
}) : null
|
|
131
|
+
]
|
|
132
|
+
}), document.body);
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { SelectionBubble };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=floating.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating.js","names":[],"sources":["../../../src/kit/controls/rich-text/floating.tsx"],"sourcesContent":["/**\n * RICH TEXT · the selection bubble: AI rewrite, style, marks, link (V2 HEAD controls/rich-text/floating.tsx).\n * V2's inline \"Ask AI\" prompt took free text; the host's AI service rewrites by preset only, so it is not drawn.\n */\nimport { createPortal } from \"react-dom\";\nimport { motion } from \"framer-motion\";\nimport { IconBold, IconCode, IconItalic, IconLink, IconMessage, IconStrikethrough, IconUnderline } from \"@tabler/icons-react\";\nimport { Sparkle } from \"../../ui/button\";\nimport { Menu, MenuContent, MenuItem, MenuTrigger } from \"../../ui/overlay\";\nimport type { AiPreset } from \"../../context\";\nimport type { RichTextFeature } from \"./codec\";\nimport { StyleMenu, ToolButton, stylesFor, type Fmt, type MarkCmd } from \"./toolbar\";\n\n/** The bubble's rewrite directions (V2: improve, shorter, punchier, grammar), as the host service's presets. */\nexport const BUBBLE_AI: { id: AiPreset; label: string }[] = [\n { id: \"improve\", label: \"Improve writing\" },\n { id: \"shorter\", label: \"Make shorter\" },\n { id: \"simplify\", label: \"Simplify\" },\n { id: \"grammar\", label: \"Fix spelling and grammar\" },\n];\n\nexport function SelectionBubble({\n rect,\n fmt,\n allows,\n saveSel,\n onAi,\n onStyle,\n onMark,\n onInlineCode,\n onLink,\n onComment,\n avoid,\n}: {\n rect: DOMRect;\n /** The editor's own toolbar row (when it is open): the bubble never sits on top of it. */\n avoid?: DOMRect | null;\n fmt: Fmt;\n allows: (f: RichTextFeature) => boolean;\n saveSel: () => void;\n /** Absent when the person has no AI (D58: ai.use) or the host has no AI service: the AI menu and its divider are not drawn. */\n onAi?: (preset: AiPreset) => void;\n onStyle: (tag: string) => void;\n onMark: (cmd: MarkCmd) => void;\n onInlineCode: () => void;\n onLink: () => void;\n onComment?: () => void;\n}) {\n // Above the selection by default; flips below it when above would cover the editor's toolbar or leave the viewport.\n const above = rect.top - 44;\n const blocked = above < 8 || (!!avoid && above < avoid.bottom + 4 && above + 36 > avoid.top);\n const top = blocked ? rect.bottom + 8 : above;\n const styles = stylesFor(allows);\n return createPortal(\n <motion.div\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.14 }}\n onMouseDown={(e) => {\n if (!(e.target as HTMLElement).closest(\"button\")) e.preventDefault();\n }}\n style={{ top, left: Math.min(window.innerWidth - 400, Math.max(8, rect.left + rect.width / 2 - 190)) }}\n data-floating-layer=\"\"\n data-kit-scope=\"\"\n className=\"pointer-events-auto fixed z-[85] flex h-9 items-center gap-0.5 rounded-kit-lg border border-kit-line bg-kit-surface px-1 text-kit-fg shadow-kit-sm [.dark_&]:border-kit-line-strong [.dark_&]:bg-[#252528]\"\n role=\"toolbar\"\n aria-label=\"Selection formatting\"\n >\n {onAi ? (\n <>\n <Menu>\n <MenuTrigger\n onMouseDown={(e) => {\n e.preventDefault();\n saveSel();\n }}\n className=\"flex h-7 items-center gap-1.5 rounded-kit-md px-2 text-kit-sm text-kit-fg hover:bg-kit-hover data-[popup-open]:bg-kit-hover\"\n >\n <Sparkle size={14} /> Improve writing\n </MenuTrigger>\n <MenuContent className=\"w-52\" finalFocus={false}>\n {BUBBLE_AI.map((p) => (\n <MenuItem key={p.id} icon={<Sparkle size={16} />} onClick={() => onAi(p.id)}>\n {p.label}\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n <span aria-hidden className=\"mx-0.5 h-4 w-px bg-kit-line\" />\n </>\n ) : null}\n {fmt.block !== \"island\" && styles.length > 1 ? (\n <>\n <StyleMenu block={fmt.block} styles={styles} onPick={onStyle} />\n <span aria-hidden className=\"mx-0.5 h-4 w-px bg-kit-line\" />\n </>\n ) : null}\n {allows(\"bold\") ? <ToolButton label=\"Bold\" icon={<IconBold stroke={1.5} />} shortcut=\"⌘B\" active={fmt.bold} onClick={() => onMark(\"bold\")} /> : null}\n {allows(\"italic\") ? <ToolButton label=\"Italic\" icon={<IconItalic stroke={1.5} />} shortcut=\"⌘I\" active={fmt.italic} onClick={() => onMark(\"italic\")} /> : null}\n {allows(\"underline\") ? <ToolButton label=\"Underline\" icon={<IconUnderline stroke={1.5} />} shortcut=\"⌘U\" active={fmt.underline} onClick={() => onMark(\"underline\")} /> : null}\n {allows(\"strike\") ? <ToolButton label=\"Strikethrough\" icon={<IconStrikethrough stroke={1.5} />} active={fmt.strike} onClick={() => onMark(\"strikeThrough\")} /> : null}\n {allows(\"code\") ? <ToolButton label=\"Inline code\" icon={<IconCode stroke={1.5} />} shortcut=\"⌘E\" onClick={onInlineCode} /> : null}\n {allows(\"link\") ? <ToolButton label=\"Link\" icon={<IconLink stroke={1.5} />} shortcut=\"⌘K\" active={fmt.onLink} onClick={onLink} /> : null}\n {onComment ? <ToolButton label=\"Comment\" icon={<IconMessage stroke={1.5} />} onClick={onComment} /> : null}\n </motion.div>,\n document.body,\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ACTIONS, CONTROLS } from "../../engine/kit-field.js";
|
|
2
|
+
import { RichTextControl, RichTextExpandAction } from "./control.js";
|
|
3
|
+
//#region src/kit/controls/rich-text/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Rich text: registers the control and its label-row action (one line each, so lanes merge cleanly).
|
|
6
|
+
* Imported for its side effect by whatever loads the kit's controls; import the parts themselves by path.
|
|
7
|
+
*/
|
|
8
|
+
CONTROLS.richtext = RichTextControl;
|
|
9
|
+
ACTIONS.richtext = RichTextExpandAction;
|
|
10
|
+
//#endregion
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/kit/controls/rich-text/index.ts"],"sourcesContent":["/**\n * Rich text: registers the control and its label-row action (one line each, so lanes merge cleanly).\n * Imported for its side effect by whatever loads the kit's controls; import the parts themselves by path.\n */\nimport { ACTIONS, CONTROLS } from \"../../engine/kit-field\";\nimport { RichTextControl, RichTextExpandAction } from \"./control\";\n\nCONTROLS.richtext = RichTextControl;\nACTIONS.richtext = RichTextExpandAction;\n"],"mappings":";;;;;;;AAOA,SAAS,WAAW;AACpB,QAAQ,WAAW"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface TextLink {
|
|
2
|
+
href: string;
|
|
3
|
+
newTab?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/** An address a link may carry: http(s), mailto, tel, a site path or an in-page anchor. */
|
|
6
|
+
export declare function linkProblem(href: string): string | null;
|
|
7
|
+
export declare function LinkForm({ initial, allowNewTab, onSave, onCancel, onDetach, }: {
|
|
8
|
+
initial: TextLink;
|
|
9
|
+
allowNewTab: boolean;
|
|
10
|
+
onSave: (v: TextLink) => void;
|
|
11
|
+
onCancel: () => void;
|
|
12
|
+
onDetach?: () => void;
|
|
13
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Button } from "../../ui/button.js";
|
|
2
|
+
import { Switch } from "../../ui/controls.js";
|
|
3
|
+
import { Input } from "../../ui/input.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { IconLink, IconUnlink } from "@tabler/icons-react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/kit/controls/rich-text/link-form.tsx
|
|
8
|
+
/**
|
|
9
|
+
* RICH TEXT · the link popover's body for a link inside the text: the address, and "Open in a new tab" when the field
|
|
10
|
+
* allows it. A text link stores its address and target only (production's link mark), so V2's link type tabs and rel
|
|
11
|
+
* choice, which belong to the link FIELD, are not offered here.
|
|
12
|
+
*/
|
|
13
|
+
/** An address a link may carry: http(s), mailto, tel, a site path or an in-page anchor. */
|
|
14
|
+
function linkProblem(href) {
|
|
15
|
+
const h = href.trim();
|
|
16
|
+
if (!h) return "Add an address first.";
|
|
17
|
+
if (/^(https?:\/\/[^\s]+|mailto:[^\s]+|tel:[+\d][\d\s()-]*|\/(?!\/)[^\s]*|#[^\s]+)$/i.test(h)) return null;
|
|
18
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(h)) return "Use an address that starts with https://, mailto: or tel:.";
|
|
19
|
+
if (/^[^\s/]+\.[^\s]+$/.test(h)) return `Add https:// in front: https://${h}`;
|
|
20
|
+
return "Use a full address (https://…), a page path (/about) or an anchor (#section).";
|
|
21
|
+
}
|
|
22
|
+
function LinkForm({ initial, allowNewTab, onSave, onCancel, onDetach }) {
|
|
23
|
+
const [href, setHref] = React.useState(initial.href);
|
|
24
|
+
const [newTab, setNewTab] = React.useState(!!initial.newTab);
|
|
25
|
+
const [problem, setProblem] = React.useState(null);
|
|
26
|
+
const urlId = React.useId();
|
|
27
|
+
const tabId = React.useId();
|
|
28
|
+
const errId = React.useId();
|
|
29
|
+
return /* @__PURE__ */ jsxs("form", {
|
|
30
|
+
className: "flex flex-col gap-2",
|
|
31
|
+
onSubmit: (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
const p = linkProblem(href);
|
|
34
|
+
setProblem(p);
|
|
35
|
+
if (!p) onSave({
|
|
36
|
+
href: href.trim(),
|
|
37
|
+
newTab: allowNewTab && newTab
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsx("label", {
|
|
42
|
+
htmlFor: urlId,
|
|
43
|
+
className: "text-kit-xs font-medium text-kit-fg-2",
|
|
44
|
+
children: "Link to"
|
|
45
|
+
}),
|
|
46
|
+
/* @__PURE__ */ jsx(Input, {
|
|
47
|
+
id: urlId,
|
|
48
|
+
autoFocus: true,
|
|
49
|
+
size: "sm",
|
|
50
|
+
value: href,
|
|
51
|
+
onChange: (e) => {
|
|
52
|
+
setHref(e.target.value);
|
|
53
|
+
if (problem) setProblem(null);
|
|
54
|
+
},
|
|
55
|
+
placeholder: "https://… or /page",
|
|
56
|
+
leading: /* @__PURE__ */ jsx(IconLink, { stroke: 1.5 }),
|
|
57
|
+
"aria-invalid": problem ? true : void 0,
|
|
58
|
+
"aria-describedby": problem ? errId : void 0
|
|
59
|
+
}),
|
|
60
|
+
problem ? /* @__PURE__ */ jsx("p", {
|
|
61
|
+
id: errId,
|
|
62
|
+
role: "alert",
|
|
63
|
+
className: "text-kit-xs text-kit-danger-fg",
|
|
64
|
+
children: problem
|
|
65
|
+
}) : null,
|
|
66
|
+
allowNewTab ? /* @__PURE__ */ jsxs("div", {
|
|
67
|
+
className: "flex items-center justify-between gap-2",
|
|
68
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
69
|
+
htmlFor: tabId,
|
|
70
|
+
className: "text-kit-sm text-kit-fg",
|
|
71
|
+
children: "Open in a new tab"
|
|
72
|
+
}), /* @__PURE__ */ jsx(Switch, {
|
|
73
|
+
id: tabId,
|
|
74
|
+
size: "sm",
|
|
75
|
+
checked: newTab,
|
|
76
|
+
onCheckedChange: setNewTab,
|
|
77
|
+
"aria-label": "Open in a new tab"
|
|
78
|
+
})]
|
|
79
|
+
}) : null,
|
|
80
|
+
/* @__PURE__ */ jsxs("div", {
|
|
81
|
+
className: "mt-1 flex items-center gap-2",
|
|
82
|
+
children: [
|
|
83
|
+
onDetach ? /* @__PURE__ */ jsx(Button, {
|
|
84
|
+
size: "xs",
|
|
85
|
+
variant: "ghost",
|
|
86
|
+
leftIcon: /* @__PURE__ */ jsx(IconUnlink, { stroke: 1.5 }),
|
|
87
|
+
onClick: onDetach,
|
|
88
|
+
children: "Remove link"
|
|
89
|
+
}) : null,
|
|
90
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
91
|
+
/* @__PURE__ */ jsx(Button, {
|
|
92
|
+
size: "xs",
|
|
93
|
+
variant: "ghost",
|
|
94
|
+
onClick: onCancel,
|
|
95
|
+
children: "Cancel"
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ jsx(Button, {
|
|
98
|
+
size: "xs",
|
|
99
|
+
variant: "primary",
|
|
100
|
+
type: "submit",
|
|
101
|
+
children: "Save"
|
|
102
|
+
})
|
|
103
|
+
]
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { LinkForm };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=link-form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-form.js","names":[],"sources":["../../../src/kit/controls/rich-text/link-form.tsx"],"sourcesContent":["/**\n * RICH TEXT · the link popover's body for a link inside the text: the address, and \"Open in a new tab\" when the field\n * allows it. A text link stores its address and target only (production's link mark), so V2's link type tabs and rel\n * choice, which belong to the link FIELD, are not offered here.\n */\nimport * as React from \"react\";\nimport { IconLink, IconUnlink } from \"@tabler/icons-react\";\nimport { Button } from \"../../ui/button\";\nimport { Switch } from \"../../ui/controls\";\nimport { Input } from \"../../ui/input\";\n\nexport interface TextLink {\n href: string;\n newTab?: boolean;\n}\n\n/** An address a link may carry: http(s), mailto, tel, a site path or an in-page anchor. */\nexport function linkProblem(href: string): string | null {\n const h = href.trim();\n if (!h) return \"Add an address first.\";\n if (/^(https?:\\/\\/[^\\s]+|mailto:[^\\s]+|tel:[+\\d][\\d\\s()-]*|\\/(?!\\/)[^\\s]*|#[^\\s]+)$/i.test(h)) return null;\n if (/^[a-z][a-z0-9+.-]*:/i.test(h)) return \"Use an address that starts with https://, mailto: or tel:.\";\n if (/^[^\\s/]+\\.[^\\s]+$/.test(h)) return `Add https:// in front: https://${h}`;\n return \"Use a full address (https://…), a page path (/about) or an anchor (#section).\";\n}\n\nexport function LinkForm({\n initial,\n allowNewTab,\n onSave,\n onCancel,\n onDetach,\n}: {\n initial: TextLink;\n allowNewTab: boolean;\n onSave: (v: TextLink) => void;\n onCancel: () => void;\n onDetach?: () => void;\n}) {\n const [href, setHref] = React.useState(initial.href);\n const [newTab, setNewTab] = React.useState(!!initial.newTab);\n const [problem, setProblem] = React.useState<string | null>(null);\n const urlId = React.useId();\n const tabId = React.useId();\n const errId = React.useId();\n return (\n <form\n className=\"flex flex-col gap-2\"\n onSubmit={(e) => {\n e.preventDefault();\n const p = linkProblem(href);\n setProblem(p);\n if (!p) onSave({ href: href.trim(), newTab: allowNewTab && newTab });\n }}\n >\n <label htmlFor={urlId} className=\"text-kit-xs font-medium text-kit-fg-2\">\n Link to\n </label>\n <Input\n id={urlId}\n autoFocus\n size=\"sm\"\n value={href}\n onChange={(e) => {\n setHref(e.target.value);\n if (problem) setProblem(null);\n }}\n placeholder=\"https://… or /page\"\n leading={<IconLink stroke={1.5} />}\n aria-invalid={problem ? true : undefined}\n aria-describedby={problem ? errId : undefined}\n />\n {problem ? (\n <p id={errId} role=\"alert\" className=\"text-kit-xs text-kit-danger-fg\">\n {problem}\n </p>\n ) : null}\n {allowNewTab ? (\n <div className=\"flex items-center justify-between gap-2\">\n <label htmlFor={tabId} className=\"text-kit-sm text-kit-fg\">\n Open in a new tab\n </label>\n <Switch id={tabId} size=\"sm\" checked={newTab} onCheckedChange={setNewTab} aria-label=\"Open in a new tab\" />\n </div>\n ) : null}\n <div className=\"mt-1 flex items-center gap-2\">\n {onDetach ? (\n <Button size=\"xs\" variant=\"ghost\" leftIcon={<IconUnlink stroke={1.5} />} onClick={onDetach}>\n Remove link\n </Button>\n ) : null}\n <span className=\"flex-1\" />\n <Button size=\"xs\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n <Button size=\"xs\" variant=\"primary\" type=\"submit\">\n Save\n </Button>\n </div>\n </form>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAiBA,SAAgB,YAAY,MAA6B;CACvD,MAAM,IAAI,KAAK,MAAM;AACrB,KAAI,CAAC,EAAG,QAAO;AACf,KAAI,kFAAkF,KAAK,EAAE,CAAE,QAAO;AACtG,KAAI,uBAAuB,KAAK,EAAE,CAAE,QAAO;AAC3C,KAAI,oBAAoB,KAAK,EAAE,CAAE,QAAO,kCAAkC;AAC1E,QAAO;;AAGT,SAAgB,SAAS,EACvB,SACA,aACA,QACA,UACA,YAOC;CACD,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,QAAQ,KAAK;CACpD,MAAM,CAAC,QAAQ,aAAa,MAAM,SAAS,CAAC,CAAC,QAAQ,OAAO;CAC5D,MAAM,CAAC,SAAS,cAAc,MAAM,SAAwB,KAAK;CACjE,MAAM,QAAQ,MAAM,OAAO;CAC3B,MAAM,QAAQ,MAAM,OAAO;CAC3B,MAAM,QAAQ,MAAM,OAAO;AAC3B,QACE,qBAAC,QAAD;EACE,WAAU;EACV,WAAW,MAAM;AACf,KAAE,gBAAgB;GAClB,MAAM,IAAI,YAAY,KAAK;AAC3B,cAAW,EAAE;AACb,OAAI,CAAC,EAAG,QAAO;IAAE,MAAM,KAAK,MAAM;IAAE,QAAQ,eAAe;IAAQ,CAAC;;YANxE;GASE,oBAAC,SAAD;IAAO,SAAS;IAAO,WAAU;cAAwC;IAEjE,CAAA;GACR,oBAAC,OAAD;IACE,IAAI;IACJ,WAAA;IACA,MAAK;IACL,OAAO;IACP,WAAW,MAAM;AACf,aAAQ,EAAE,OAAO,MAAM;AACvB,SAAI,QAAS,YAAW,KAAK;;IAE/B,aAAY;IACZ,SAAS,oBAAC,UAAD,EAAU,QAAQ,KAAO,CAAA;IAClC,gBAAc,UAAU,OAAO,KAAA;IAC/B,oBAAkB,UAAU,QAAQ,KAAA;IACpC,CAAA;GACD,UACC,oBAAC,KAAD;IAAG,IAAI;IAAO,MAAK;IAAQ,WAAU;cAClC;IACC,CAAA,GACF;GACH,cACC,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,SAAD;KAAO,SAAS;KAAO,WAAU;eAA0B;KAEnD,CAAA,EACR,oBAAC,QAAD;KAAQ,IAAI;KAAO,MAAK;KAAK,SAAS;KAAQ,iBAAiB;KAAW,cAAW;KAAsB,CAAA,CACvG;QACJ;GACJ,qBAAC,OAAD;IAAK,WAAU;cAAf;KACG,WACC,oBAAC,QAAD;MAAQ,MAAK;MAAK,SAAQ;MAAQ,UAAU,oBAAC,YAAD,EAAY,QAAQ,KAAO,CAAA;MAAE,SAAS;gBAAU;MAEnF,CAAA,GACP;KACJ,oBAAC,QAAD,EAAM,WAAU,UAAW,CAAA;KAC3B,oBAAC,QAAD;MAAQ,MAAK;MAAK,SAAQ;MAAQ,SAAS;gBAAU;MAE5C,CAAA;KACT,oBAAC,QAAD;MAAQ,MAAK;MAAK,SAAQ;MAAU,MAAK;gBAAS;MAEzC,CAAA;KACL;;GACD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function htmlToMarkdown(html: string): string;
|
|
2
|
+
export declare function inlineMd(src: string): string;
|
|
3
|
+
/** Throws on Markdown it cannot read (e.g. an unclosed code fence). */
|
|
4
|
+
export declare function markdownToHtml(md: string): string;
|
|
5
|
+
/** Does pasted plain text look like Markdown worth converting into blocks? */
|
|
6
|
+
export declare const looksLikeMarkdown: (t: string) => boolean;
|