@bettercms-ai/kit 0.1.1 → 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":"link.js","names":[],"sources":["../../src/kit/controls/link.tsx"],"sourcesContent":["/**\n * LINK — the ONE link element of the product (V2 HEAD kit/controls/link.tsx, DESIGN §8.7, CPO D43 · D48 · D57).\n *\n * - <LinkForm> Type (Page · CMS item · URL · Email · Phone · Section · File) → the target for that type (search over\n * the host's pages and CMS items, paste detection, URL / email / phone / #anchor validation; File =\n * the host's media library) → Section on the picked page → options (new tab · rel · email subject).\n * - <LinkPopoverBody> the link panel: what it links to now + LinkForm + Remove link · Cancel · Apply.\n * - <LinkField> a link at rest (one bordered row): click edits in place (quick edit), the sliders icon opens the panel.\n * - <LinkPicker> the target input inside all of the above.\n * - <LinkLine> how a link READS at rest: page icon + title + path · external icon + domain · mail / phone.\n *\n * Where the targets come from. The kit never fetches: the host hands its own link-target query in as a React hook,\n * `KitServices.useLinkTargets` (KitLinkServices below), and the media library as `KitServices.MediaPicker`. With no hook a\n * page link is typed as a path and the list says so in words; with no media picker the File type is not offered.\n * Section anchors come from the host that knows the page (SectionAnchorsProvider); without one a section is typed (#faq).\n *\n * Stored shape (prod `link`, adapters/values.ts linkToProd / linkFromProd). The kit value is what the field already\n * stores: a STRING href stays a string (legacy fields and the sites that read `href={link}`), an object stays an object.\n * An empty field takes `field.valueShape` and, with none, the string (prod LinkField's default). In the string shape the\n * options (new tab, rel) need the object, so they hide — V2's `valueShape=\"string\"`. An object never carries `target`\n * (derived from newTab), `rel: \"follow\"` (follow = no rel) or `newTab: false`, so it reads back exactly as written.\n *\n * Deviations from V2, each because prod has no source for it: no \"From this entry\" {{token}} targets (no binding store\n * behind them), no seeded page anchors, no fabricated CDN address for a file (a file without a public url is refused).\n */\nimport * as React from \"react\";\nimport {\n IconAdjustmentsHorizontal, IconArrowUpRight, IconAt, IconCheck, IconChevronDown, IconExternalLink, IconFile, IconFileDatabase,\n IconFolderOpen, IconHash, IconLink, IconMail, IconPaperclip, IconPhone, IconWorld, IconX,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { isObj } from \"../lib/path\";\nimport { useKitEnv, useKitServices, type KitMediaAsset, type KitServices } from \"../context\";\nimport { Button, IconButton } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Switch } from \"../ui/controls\";\nimport { Select } from \"../ui/select\";\nimport { Menu, MenuContent, MenuItem, MenuTrigger, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Tooltip } from \"../ui/overlay\";\nimport type { ControlProps } from \"../types\";\n\nexport type LinkType = \"page\" | \"url\" | \"section\" | \"email\" | \"phone\" | \"file\" | \"entry\";\nexport type LinkRel = \"follow\" | \"nofollow\" | \"ugc\" | \"sponsored\";\nexport type ButtonStyle = \"primary\" | \"secondary\" | \"outline\" | \"link\";\nexport interface LinkValue {\n type?: LinkType;\n href: string;\n /** button label / link text */\n label?: string;\n /** resolved title of the target (page or entry name) */\n title?: string;\n pageId?: string;\n entryId?: string;\n anchor?: string;\n assetId?: string;\n email?: string;\n subject?: string;\n phone?: string;\n /** legacy target: read as newTab, never written */\n target?: \"_self\" | \"_blank\";\n newTab?: boolean;\n rel?: LinkRel;\n /* button-only (controls/button.tsx) */\n style?: ButtonStyle;\n variant?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n arrow?: boolean;\n icon?: string;\n fullWidth?: boolean;\n}\n\n/* ── Host services ───────────────────────────────────────────────────── */\n/** A place a link can point at, as the host lists it. */\nexport interface LinkTarget {\n id: string;\n title: string;\n /** the public path (\"/about\", \"/blog/hello\") or a file's url */\n href: string;\n kind: \"page\" | \"entry\" | \"file\" | \"section\";\n /** collection name for an entry, file kind for a file */\n meta?: string;\n /** list group: \"Pages\", the collection's name, \"Files\", \"On this page\" */\n group: string;\n /** draft · published · scheduled · archived … (shown when it is not live) */\n status?: string;\n /** \"#faq\" anchors on that page, when the host knows them */\n anchors?: string[];\n /** a section without an anchor yet gets it when picked */\n onChoose?: () => void;\n}\n/**\n * The link services a host provides next to KitServices (registerKitServices / KitServicesProvider take them as is).\n * `useLinkTargets` is a React HOOK (called on every render of a link control), so a host passes the same function for\n * the life of the form.\n */\nexport type KitLinkServices = Pick<KitServices, \"useLinkTargets\">;\ntype LinkHost = { targets: LinkTarget[]; loading: boolean; error?: string; unavailable: boolean };\nconst NO_TARGETS: LinkTarget[] = [];\nconst useNoTargets = () => ({ targets: NO_TARGETS, loading: false, error: undefined as string | undefined });\n\n/** The host's pages, CMS items (and files, when it lists them). */\nexport function useLinkTargets(): LinkHost {\n const svc = useKitServices();\n const useHost = svc.useLinkTargets ?? useNoTargets;\n const r = useHost();\n return { targets: r.targets ?? NO_TARGETS, loading: !!r.loading, error: r.error, unavailable: !svc.useLinkTargets };\n}\n\n/** A section on the page being edited that a link can jump to (`id` on the block). */\nexport interface SectionAnchor {\n /** \"#faq\" */\n anchor: string;\n /** what a person reads: the block's name */\n label: string;\n /** the block has no anchor yet: give it this one when a link picks it */\n ensure?: () => void;\n}\nconst SectionAnchorsCtx = React.createContext<SectionAnchor[] | null>(null);\n/** The host that knows the page being edited lists its section anchors, so the Section type is a pick. */\nexport function SectionAnchorsProvider({ anchors, children }: { anchors: SectionAnchor[]; children: React.ReactNode }) {\n return <SectionAnchorsCtx.Provider value={anchors}>{children}</SectionAnchorsCtx.Provider>;\n}\nfunction useSectionTargets(): LinkTarget[] {\n const anchors = React.useContext(SectionAnchorsCtx);\n return React.useMemo(\n () =>\n (anchors ?? []).map((a) => ({\n id: `section:${a.anchor}`,\n title: a.label,\n href: a.anchor.startsWith(\"#\") ? a.anchor : `#${a.anchor}`,\n kind: \"section\" as const,\n group: \"On this page\",\n onChoose: a.ensure,\n })),\n [anchors],\n );\n}\n\n/** A file from the media library as a link target, or the reason it can't be one. */\nexport function fileTarget(a: Pick<KitMediaAsset, \"id\" | \"name\" | \"url\">): LinkTarget | { problem: string } {\n if (!a.url || a.url.startsWith(\"blob:\")) return { problem: \"This file has no public address yet. Wait for the upload to finish, then pick it again.\" };\n const name = a.name || fileName(a.url);\n return { id: a.id, title: name, href: a.url, kind: \"file\", meta: name.split(\".\").pop()?.toUpperCase(), group: \"Files\" };\n}\n\n/* ── Value helpers ───────────────────────────────────────────────────── */\nexport const normLink = (v: unknown): LinkValue => {\n const o: LinkValue = typeof v === \"string\" ? { href: v } : isObj(v) ? ({ ...(v as object), href: typeof v.href === \"string\" ? v.href : \"\" } as LinkValue) : { href: \"\" };\n if (o.newTab === undefined && o.target === \"_blank\") o.newTab = true;\n if (!o.type) o.type = detectType(o.href);\n return o;\n};\n\nexport function detectType(raw: string): LinkType {\n const s = raw.trim();\n if (!s) return \"page\";\n if (s.startsWith(\"#\")) return \"section\";\n if (/^mailto:/i.test(s) || /^[^\\s@/]+@[^\\s@]+\\.[^\\s@]+$/.test(s)) return \"email\";\n if (/^tel:/i.test(s) || /^\\+?[\\d\\s().-]{7,}$/.test(s)) return \"phone\";\n if (/\\.(pdf|zip|docx?|csv)$/i.test(s)) return \"file\";\n if (/^https?:\\/\\//i.test(s) || /^www\\./i.test(s) || /^[a-z0-9-]+(\\.[a-z0-9-]+)+(\\/|$)/i.test(s)) return \"url\";\n return \"page\";\n}\n\nexport const LINK_TYPES: { type: LinkType; label: string; icon: React.ReactNode; placeholder: string; target: string }[] = [\n { type: \"page\", label: \"Page\", icon: <IconFile stroke={1.5} />, placeholder: \"Search pages and CMS items, or paste a link\", target: \"Page\" },\n { type: \"entry\", label: \"CMS item\", icon: <IconFileDatabase stroke={1.5} />, placeholder: \"Search CMS items\", target: \"CMS item\" },\n { type: \"url\", label: \"URL\", icon: <IconWorld stroke={1.5} />, placeholder: \"https://example.com\", target: \"Address\" },\n { type: \"email\", label: \"Email\", icon: <IconAt stroke={1.5} />, placeholder: \"name@company.com\", target: \"Email address\" },\n { type: \"phone\", label: \"Phone\", icon: <IconPhone stroke={1.5} />, placeholder: \"+1 541 555 0182\", target: \"Phone number\" },\n { type: \"section\", label: \"Section\", icon: <IconHash stroke={1.5} />, placeholder: \"#section-on-this-page\", target: \"Section on this page\" },\n { type: \"file\", label: \"File\", icon: <IconPaperclip stroke={1.5} />, placeholder: \"Search files\", target: \"File\" },\n];\nconst typeMeta = (t?: string) => LINK_TYPES.find((x) => x.type === t) ?? LINK_TYPES[0];\n\n/** The target a value points at: by id first, then by an exact path (\"/about\" typed by hand still reads as About). */\nexport function findTarget(targets: LinkTarget[], v: LinkValue): LinkTarget | undefined {\n const byId = targets.find((t) => (v.pageId && t.id === v.pageId) || (v.entryId && t.id === v.entryId) || (v.assetId && t.id === v.assetId));\n if (byId) return byId;\n if (v.type === \"section\") return v.href ? targets.find((t) => t.kind === \"section\" && t.href === (v.href.startsWith(\"#\") ? v.href : `#${v.href}`)) : undefined;\n if (!v.href || (v.type !== \"page\" && v.type !== \"entry\" && v.type !== \"file\")) return undefined;\n if (v.type === \"file\") {\n const f = targets.find((t) => t.kind === \"file\" && t.href === v.href);\n // a file picked from the library reads as the file by the name stored with it\n return f ?? (v.title ? { id: v.assetId ?? v.href, title: v.title, href: v.href, kind: \"file\", group: \"Files\" } : undefined);\n }\n const path = v.href.replace(/[?#].*$/, \"\").replace(/\\/$/, \"\") || \"/\";\n return targets.find((t) => t.kind !== \"file\" && t.kind !== \"section\" && t.href === path);\n}\n\n/** The final href for a link value. */\nexport function hrefOf(v: LinkValue): string {\n switch (v.type) {\n case \"email\": {\n const addr = (v.email ?? v.href).replace(/^mailto:/i, \"\").replace(/\\?.*$/, \"\");\n return addr ? `mailto:${addr}${v.subject ? `?subject=${encodeURIComponent(v.subject)}` : \"\"}` : \"\";\n }\n case \"phone\": {\n const n = (v.phone ?? v.href).replace(/^tel:/i, \"\").replace(/[^\\d+]/g, \"\");\n return n ? `tel:${n}` : \"\";\n }\n case \"section\":\n return v.href.startsWith(\"#\") ? v.href : v.href ? `#${v.href}` : \"\";\n default: {\n // idempotent: a stored href already carries its anchor, so a changed or removed anchor replaces it\n const base = v.anchor !== undefined ? v.href.replace(/#.*$/, \"\") : v.href;\n return `${base}${v.anchor && v.anchor !== \"none\" ? v.anchor : \"\"}`;\n }\n }\n}\n\nconst BAD_URL = \"Enter a full address, like https://example.com.\";\n/** Why a link can't be saved yet, in plain words. Undefined when it is fine (or empty). */\nexport function linkProblem(v: LinkValue): string | undefined {\n if (!hasLink(v)) return undefined;\n const raw = (v.type === \"email\" ? v.email ?? v.href : v.type === \"phone\" ? v.phone ?? v.href : v.href).trim();\n if (/^(javascript|data|vbscript):/i.test(raw.replace(/[\\u0000- ]/g, \"\"))) return \"Script links aren't allowed.\";\n switch (v.type) {\n case \"url\": {\n if (raw.startsWith(\"/\") || raw.startsWith(\"#\")) return undefined;\n try {\n const u = new URL(/^[a-z][a-z0-9+.-]*:/i.test(raw) ? raw : `https://${raw}`);\n if (!/^https?:$/.test(u.protocol)) return BAD_URL;\n return /\\.[a-z]{2,}$/i.test(u.hostname) || u.hostname === \"localhost\" ? undefined : BAD_URL;\n } catch {\n return BAD_URL;\n }\n }\n case \"email\":\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/.test(raw.replace(/^mailto:/i, \"\").replace(/\\?.*$/, \"\")) ? undefined : \"Enter an email address, like name@company.com.\";\n case \"phone\":\n return raw.replace(/^tel:/i, \"\").replace(/\\D/g, \"\").length >= 7 ? undefined : \"Enter a phone number with at least 7 digits.\";\n case \"section\":\n return /^#?[A-Za-z][\\w-]*$/.test(raw) ? undefined : \"Use letters, numbers and dashes, like #faq.\";\n case \"page\":\n case \"entry\":\n return raw.startsWith(\"/\") || raw.startsWith(\"#\") || v.pageId || v.entryId ? undefined : \"Pick a page, or start a path with /, like /about.\";\n default:\n return undefined;\n }\n}\n\n/** One list for every link editor (dropdown, never a segmented row — D40). */\nexport const REL_ITEMS: { value: LinkRel; label: string; description: string }[] = [\n { value: \"follow\", label: \"Do-follow\", description: \"Normal link. Search engines follow it.\" },\n { value: \"nofollow\", label: \"No-follow\", description: \"Search engines don't follow or credit it.\" },\n { value: \"sponsored\", label: \"Sponsored\", description: \"Paid, affiliate or ad link.\" },\n { value: \"ugc\", label: \"UGC\", description: \"Link added by users, e.g. comments.\" },\n];\n\nexport const hasLink = (v: LinkValue) => !!(v.href || v.email || v.phone);\nexport const TARGET_KEYS = { title: undefined, pageId: undefined, entryId: undefined, assetId: undefined, anchor: undefined } as const;\n\n/** The value a picked target produces (keeps label, style and options). */\nexport function withTarget(v: LinkValue, t: LinkTarget): LinkValue {\n return {\n ...v,\n ...TARGET_KEYS,\n email: undefined,\n phone: undefined,\n subject: undefined,\n type: t.kind === \"file\" ? \"file\" : t.kind === \"entry\" ? \"entry\" : t.kind === \"section\" ? \"section\" : \"page\",\n href: t.href,\n title: t.title,\n pageId: t.kind === \"page\" ? t.id : undefined,\n entryId: t.kind === \"entry\" ? t.id : undefined,\n assetId: t.kind === \"file\" ? t.id : undefined,\n };\n}\n/** The value typed text produces (auto-detects URL / email / phone / #section unless the type was chosen). */\nexport function withText(v: LinkValue, s: string, type?: LinkType): LinkValue {\n const t = type ?? detectType(s);\n const n: LinkValue = { ...v, ...TARGET_KEYS, type: t, email: undefined, phone: undefined };\n if (t === \"email\") Object.assign(n, { email: s.replace(/^mailto:/i, \"\"), href: s });\n else if (t === \"phone\") Object.assign(n, { phone: s.replace(/^tel:/i, \"\"), href: s });\n else n.href = s;\n return n;\n}\n/** Clean a value before it is stored: add https:// to bare domains, refuse script URLs, store the href the site renders. */\nexport function finalizeLink(v: LinkValue): LinkValue | null {\n const out: LinkValue = { ...v };\n if (/^(javascript|data|vbscript):/i.test(out.href.replace(/[\\u0000- ]/g, \"\"))) return null;\n if (out.type === \"url\" && out.href && !/^(https?:|\\/|#)/.test(out.href)) out.href = `https://${out.href.replace(/^\\/+/, \"\")}`;\n // the stored href is the one the site renders (mailto:, tel:, #anchor); every consumer reads `href` as is\n if (hasLink(out)) out.href = hrefOf(out);\n return out;\n}\n/**\n * The object as prod stores it, keyed like the value it replaces (`original`), so an edit changes only what was edited:\n * no undefined keys; no `rel: \"follow\"` (follow is no rel: the backend normalises it away and a button refuses it); no\n * `newTab: false` and no `target` unless the stored value had that key (a stored `target` is kept in sync with newTab,\n * and is then the one that carries it).\n */\nexport function storedLink<T extends LinkValue>(v: T, original?: unknown): T {\n const had = (k: string) => isObj(original) && k in original;\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v)) {\n if (x === undefined || k === \"target\") continue;\n if (k === \"rel\" && x === \"follow\") continue;\n if (k === \"newTab\" && !had(\"newTab\") && (x === false || had(\"target\"))) continue;\n out[k] = x;\n }\n if (had(\"target\")) out.target = v.newTab ? \"_blank\" : \"_self\";\n return out as T;\n}\n/** Text the picker's input shows for a value that has no picked target. */\nconst inputText = (v: LinkValue) =>\n v.type === \"email\" ? (v.email ?? v.href.replace(/^mailto:/i, \"\")) : v.type === \"phone\" ? (v.phone ?? v.href.replace(/^tel:/i, \"\")) : v.href;\n\nconst STATUS_LABEL: Record<string, string> = { draft: \"Draft\", changed: \"Edited\", scheduled: \"Scheduled\", review: \"In review\", archived: \"Archived\" };\n\n/* ── How a link reads ───────────────────────────────────────────────── */\nexport function linkIcon(v: LinkValue, target?: LinkTarget): React.ReactNode {\n if (!hasLink(v)) return <IconLink stroke={1.5} />;\n if (target) return target.kind === \"entry\" ? <IconFileDatabase stroke={1.5} /> : target.kind === \"file\" ? <IconPaperclip stroke={1.5} /> : target.kind === \"section\" ? <IconHash stroke={1.5} /> : <IconFile stroke={1.5} />;\n switch (v.type) {\n case \"url\": return <IconExternalLink stroke={1.5} />;\n case \"email\": return <IconMail stroke={1.5} />;\n case \"phone\": return <IconPhone stroke={1.5} />;\n case \"section\": return <IconHash stroke={1.5} />;\n case \"file\": return <IconPaperclip stroke={1.5} />;\n case \"entry\": return <IconFileDatabase stroke={1.5} />;\n default: return <IconFile stroke={1.5} />;\n }\n}\n/** Primary + secondary text: page title + path · domain + rest of the URL · address · number. */\nexport function describeLink(v: LinkValue, target?: LinkTarget): { primary: string; secondary?: string } {\n if (!hasLink(v)) return { primary: \"\" };\n const anchor = v.anchor && v.anchor !== \"none\" ? v.anchor : \"\";\n if (target) return { primary: target.title, secondary: target.kind === \"section\" ? `${target.href} on this page` : target.kind === \"file\" ? fileKind(target) : `${target.href}${anchor}` };\n switch (v.type) {\n case \"url\": {\n try {\n const u = new URL(/^https?:/i.test(v.href) ? v.href : `https://${v.href}`);\n const rest = `${u.pathname === \"/\" ? \"\" : u.pathname}${u.search}${u.hash}`;\n return { primary: u.hostname.replace(/^www\\./, \"\"), secondary: rest || undefined };\n } catch {\n return { primary: v.href };\n }\n }\n case \"email\": return { primary: v.email ?? v.href.replace(/^mailto:/i, \"\").replace(/\\?.*$/, \"\"), secondary: v.subject ? `Subject: ${v.subject}` : undefined };\n case \"phone\": return { primary: v.phone ?? v.href.replace(/^tel:/i, \"\") };\n case \"section\": return { primary: v.href, secondary: \"On this page\" };\n // a stored href already carries its anchor (finalizeLink)\n default: return { primary: v.title || v.href, secondary: v.title ? v.href : undefined };\n }\n}\n/** \"PDF file\": the name is already the title */\nconst fileKind = (t: LinkTarget) => `${t.meta ?? (fileName(t.href).split(\".\").pop() ?? \"\").toUpperCase()} file`.trim();\nfunction fileName(href: string) {\n const last = href.replace(/[?#].*$/, \"\").split(\"/\").pop() ?? href;\n try {\n return decodeURIComponent(last);\n } catch {\n return last;\n }\n}\n/** What a person reads for a link (one string — menus, aria labels, history). */\nexport const linkText = (v: LinkValue) => (hasLink(v) ? v.title || describeLink(v).primary : \"\");\n\n/** A link at rest: icon · title (fg) · path (fg-3) · new-tab mark. Empty → \"Add link\". */\nexport function LinkLine({ v, target, placeholder = \"Add link\", className }: { v: LinkValue; target?: LinkTarget; placeholder?: string; className?: string }) {\n const d = describeLink(v, target);\n const empty = !hasLink(v);\n return (\n <span className={cn(\"flex min-w-0 flex-1 items-center gap-2\", className)}>\n <span className={cn(\"flex shrink-0 [&_svg]:size-4\", empty ? \"text-kit-fg-3\" : \"text-kit-fg-2\")} aria-hidden>{linkIcon(v, target)}</span>\n <span className={cn(\"min-w-0 shrink truncate text-kit-sm\", empty ? \"text-kit-fg-3\" : \"text-kit-fg\")}>{empty ? placeholder : d.primary}</span>\n {d.secondary ? <span className=\"min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3\">{d.secondary}</span> : <span className=\"flex-1\" />}\n {!empty && v.newTab ? (\n <span className=\"inline-flex shrink-0 items-center gap-0.5 text-kit-2xs text-kit-fg-3\">\n <IconArrowUpRight className=\"size-3\" stroke={1.5} aria-hidden />\n New tab\n </span>\n ) : null}\n </span>\n );\n}\n\n/* ── The picker: ONE link input for the whole product ───────────────── */\ntype Row = { key: string; group: string; target: LinkTarget };\n\n/** While the media library is open from a picker, focus sits in its dialog: a quick edit must not close under it. */\nlet libraryOpen = false;\n/** Marks the floating results list, so a quick edit losing focus to it is not \"focus left the editor\". */\nconst LIST_ATTR = \"data-kit-link-list\";\n\nexport interface LinkPickerProps {\n value: LinkValue;\n /** every change: typed text, a picked target, a cleared value */\n onChange: (v: LinkValue) => void;\n /** a target was chosen from the list (quick editors commit here) */\n onPick?: (v: LinkValue) => void;\n /** Enter with no list row active */\n onEnter?: (v: LinkValue) => void;\n /** Escape with the list closed */\n onEscape?: () => void;\n autoFocus?: boolean;\n /** open straight into search (quick edit), even when a target is picked */\n startSearching?: boolean;\n id?: string;\n \"aria-label\"?: string;\n size?: \"sm\" | \"md\";\n /** no border of its own — it sits inside a unit that already draws one (button field) */\n bare?: boolean;\n /** the host shows its own type control (link panel): hide the inline type menu and search only this type */\n lockedType?: LinkType;\n /** results render in the flow under the input instead of a floating list — panels/popovers, never over them */\n inlineList?: boolean;\n /** the link types this place allows. Default: all of them */\n types?: LinkType[];\n /** the value can't be saved as it is (shown as the field's error state) */\n invalid?: boolean;\n \"aria-describedby\"?: string;\n className?: string;\n}\n\nexport function LinkPicker({\n value, onChange, onPick, onEnter, onEscape, autoFocus, startSearching, id, \"aria-label\": ariaLabel = \"Link to\", size = \"md\", bare, lockedType,\n inlineList, types, invalid, \"aria-describedby\": describedBy, className,\n}: LinkPickerProps) {\n const v = normLink(value);\n const host = useLinkTargets();\n const sections = useSectionTargets();\n const { MediaPicker } = useKitServices();\n const targets = React.useMemo(() => [...host.targets, ...sections], [host.targets, sections]);\n const picked = findTarget(targets, v);\n const [library, setLibraryState] = React.useState(false);\n const setLibrary = (o: boolean) => {\n libraryOpen = o;\n setLibraryState(o);\n };\n React.useEffect(() => () => void (libraryOpen = false), []);\n const [fileProblem, setFileProblem] = React.useState<string>();\n const [searching, setSearching] = React.useState(!!startSearching || !picked);\n const [text, setText] = React.useState(() => (picked ? \"\" : inputText(v)));\n const [manualTypeState, setManualType] = React.useState<LinkType | null>(null);\n const manualType = lockedType ?? manualTypeState;\n const [open, setOpen] = React.useState(false);\n const [active, setActive] = React.useState(-1);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const listId = React.useId();\n const type = manualType ?? v.type ?? \"page\";\n const meta = typeMeta(manualType ?? (searching && !text ? \"page\" : v.type));\n const showChip = !!picked && !searching;\n\n React.useEffect(() => {\n if (autoFocus)\n requestAnimationFrame(() => {\n inputRef.current?.focus({ preventScroll: true });\n inputRef.current?.select(); // quick edit: typing replaces, paste replaces\n });\n }, [autoFocus]);\n\n /* rows: the host's pages + every collection's entries (+ files when it lists them) */\n const q = text.trim().toLowerCase().replace(/^[/#]/, \"\");\n const searchable = type === \"page\" || type === \"entry\" || type === \"file\" || (type === \"section\" && sections.length > 0);\n const urlish = type !== \"section\" && (/^(https?:|www\\.|mailto:|tel:|#)/i.test(text.trim()) || (text.trim() !== \"\" && detectType(text) !== \"page\" && !manualType));\n const rows: Row[] = React.useMemo(() => {\n if (!searchable || urlish) return [];\n const pool = targets.filter((t) => (type === \"file\" ? t.kind === \"file\" : type === \"entry\" ? t.kind === \"entry\" : type === \"section\" ? t.kind === \"section\" : t.kind === \"page\" || t.kind === \"entry\"));\n const hit = (t: LinkTarget) => !q || t.title.toLowerCase().includes(q) || t.href.toLowerCase().includes(q) || (t.meta ?? \"\").toLowerCase().includes(q);\n const out: Row[] = [];\n const perGroup = new Map<string, number>();\n const cap = q ? 6 : type === \"page\" ? 4 : 6;\n for (const t of pool) {\n if (!hit(t)) continue;\n const n = perGroup.get(t.group) ?? 0;\n if (n >= cap) continue;\n perGroup.set(t.group, n + 1);\n out.push({ key: `${t.kind}:${t.id}`, group: t.group, target: t });\n }\n // keep each group together, groups in first-seen order (Pages first)\n const order = [...new Set(out.map((r) => r.group))];\n return out.sort((a, b) => order.indexOf(a.group) - order.indexOf(b.group)).slice(0, 24);\n }, [targets, type, q, searchable, urlish]);\n /* No silent empty list: when nothing can be listed, the list says why in one line. */\n const note: string | undefined = (() => {\n if (!searchable || urlish || rows.length) return undefined;\n if (type === \"section\") return undefined;\n if (type === \"file\") return MediaPicker ? \"Choose a file from the library with the folder button.\" : undefined;\n if (host.unavailable) return \"Page search isn't available here. Type a path, like /about.\";\n if (host.error) return `${host.error.replace(/\\.?$/, \".\")} Type a path, like /about.`;\n if (host.loading) return \"Loading pages…\";\n return q ? `Nothing matches “${text.trim()}”. Type a path, like /about.` : type === \"entry\" ? \"No CMS items yet.\" : \"No pages yet. Type a path, like /about.\";\n })();\n const listOpen = open && searching && (rows.length > 0 || !!note);\n /* Esc closes the results first, the surrounding panel only on the next Esc: the list claims the key on window, in the\n capture phase, while it is open. */\n React.useEffect(() => {\n if (!listOpen) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || !wrapRef.current?.contains(document.activeElement)) return;\n e.preventDefault();\n e.stopPropagation();\n setOpen(false);\n };\n window.addEventListener(\"keydown\", onKey, true);\n return () => window.removeEventListener(\"keydown\", onKey, true);\n }, [listOpen]);\n\n const choose = (t: LinkTarget) => {\n t.onChoose?.();\n const n = withTarget(v, t);\n setText(\"\");\n setManualType(null);\n setSearching(false);\n setOpen(false);\n setFileProblem(undefined);\n onChange(n);\n onPick?.(n);\n };\n const type_ = (s: string) => {\n setText(s);\n setOpen(true);\n setActive(s.trim() ? 0 : -1);\n onChange(withText(v, s, manualType ?? undefined));\n };\n const clear = () => {\n setText(\"\");\n setManualType(null);\n setSearching(true);\n onChange({ ...withText(v, \"\"), href: \"\" });\n requestAnimationFrame(() => inputRef.current?.focus());\n };\n const setType = (t: LinkType) => {\n setManualType(t);\n setText(\"\");\n setSearching(true);\n onChange({ ...withText(v, \"\", t), href: \"\" });\n setOpen(true);\n requestAnimationFrame(() => inputRef.current?.focus());\n };\n\n const h = size === \"sm\" ? \"h-8\" : \"h-9\";\n const list = (\n <div id={listId} role=\"listbox\" aria-label={type === \"file\" ? \"Files\" : type === \"section\" ? \"Sections on this page\" : \"Pages and CMS items\"} className=\"max-h-72 overflow-y-auto overscroll-contain\">\n {rows.map((r, i) => (\n <React.Fragment key={r.key}>\n {i === 0 || rows[i - 1].group !== r.group ? (\n <div role=\"presentation\" className=\"px-2 pb-1 pt-2 text-kit-xs font-medium text-kit-fg-3 first:pt-1\">\n {r.group}\n </div>\n ) : null}\n <div\n id={`${listId}-${i}`}\n role=\"option\"\n aria-selected={i === active}\n onMouseEnter={() => setActive(i)}\n onClick={() => choose(r.target)}\n className={cn(\"flex h-8 cursor-pointer items-center gap-2 rounded-kit-md px-2 text-kit-sm\", i === active && \"bg-kit-hover\")}\n >\n <span className=\"flex shrink-0 text-kit-fg-3 [&_svg]:size-4\" aria-hidden>\n {linkIcon({ href: r.target.href, type: r.target.kind }, r.target)}\n </span>\n <span className=\"min-w-0 shrink truncate text-kit-fg\">{r.target.title}</span>\n <span className=\"min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3\">{r.target.kind === \"file\" ? fileName(r.target.href) : r.target.href}</span>\n {r.target.status && STATUS_LABEL[r.target.status] ? <span className=\"shrink-0 text-kit-2xs text-kit-fg-3\">{STATUS_LABEL[r.target.status]}</span> : null}\n </div>\n </React.Fragment>\n ))}\n {!rows.length && note ? (\n <p role=\"status\" className=\"px-2 py-1.5 text-kit-xs text-kit-fg-3\">\n {note}\n </p>\n ) : rows.length && host.error && type !== \"file\" && type !== \"section\" ? (\n /* some targets loaded and some did not (a collection's items): the gap is named under the list */\n <p role=\"status\" className=\"px-2 py-1.5 text-kit-xs text-kit-fg-3\">\n {host.error.replace(/\\.?$/, \".\")}\n </p>\n ) : null}\n </div>\n );\n const allowed = LINK_TYPES.filter((t) => (!types || types.includes(t.type)) && (t.type !== \"file\" || MediaPicker || v.type === \"file\"));\n const typeMenu = (\n <Menu>\n <MenuTrigger\n render={\n <button\n type=\"button\"\n aria-label={`Link type: ${meta.label}`}\n className=\"ml-0.5 flex h-7 shrink-0 items-center gap-0.5 rounded-kit-md px-1.5 text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover [&_svg]:size-3.5\"\n />\n }\n >\n {meta.icon}\n <IconChevronDown className=\"!size-3\" stroke={1.5} />\n </MenuTrigger>\n <MenuContent className=\"min-w-48\">\n {allowed.map((t) => (\n <MenuItem key={t.type} icon={t.icon} onClick={() => setType(t.type)}>\n <span className=\"flex w-full items-center justify-between gap-3\">\n {t.label}\n {t.type === type ? <IconCheck className=\"size-3.5 text-kit-fg-2\" stroke={2} /> : null}\n </span>\n </MenuItem>\n ))}\n </MenuContent>\n </Menu>\n );\n\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1\", className)}>\n <Popover open={listOpen && !inlineList} onOpenChange={(o) => !o && setOpen(false)}>\n <div ref={wrapRef} className=\"min-w-0\">\n <PopoverAnchor\n className={cn(\n \"flex min-w-0 items-center\",\n bare\n ? \"bg-transparent\"\n : \"rounded-kit-md border border-kit-field-border bg-kit-field-bg shadow-kit-field transition-colors hover:border-kit-field-border-hover focus-within:border-kit-field-border-focus\",\n !bare && invalid && \"border-[var(--kit-field-invalid)] hover:border-[var(--kit-field-invalid)]\",\n h,\n )}\n >\n {showChip ? (\n <>\n <span className=\"ml-2 flex shrink-0 text-kit-fg-2 [&_svg]:size-4\" aria-hidden>\n {linkIcon(v, picked)}\n </span>\n <button\n id={id}\n type=\"button\"\n onClick={() => {\n setSearching(true);\n setOpen(true);\n requestAnimationFrame(() => inputRef.current?.focus());\n }}\n aria-label={`${ariaLabel}: ${picked!.title}, ${picked!.href}. Change`}\n className=\"flex h-full min-w-0 flex-1 items-center gap-2 px-2 text-left outline-none\"\n >\n <span className=\"min-w-0 shrink truncate text-kit-sm text-kit-fg\">{picked!.title}</span>\n <span className=\"min-w-0 flex-1 truncate text-kit-xs text-kit-fg-3\">{describeLink(v, picked).secondary}</span>\n </button>\n <IconButton label=\"Clear link\" size=\"xs\" className=\"mr-1\" onClick={clear}>\n <IconX stroke={1.5} />\n </IconButton>\n </>\n ) : (\n <>\n {lockedType !== undefined || inlineList ? (\n <span className=\"ml-2.5 flex shrink-0 text-kit-fg-3 [&_svg]:size-4\" aria-hidden>\n {meta.icon}\n </span>\n ) : (\n typeMenu\n )}\n <input\n ref={inputRef}\n id={id}\n role=\"combobox\"\n aria-label={ariaLabel}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n aria-expanded={listOpen}\n aria-controls={listOpen ? listId : undefined}\n aria-autocomplete=\"list\"\n aria-activedescendant={listOpen && active >= 0 && rows[active] ? `${listId}-${active}` : undefined}\n value={text}\n onChange={(e) => type_(e.target.value)}\n onFocus={() => setOpen(true)}\n onBlur={(e) => {\n if (wrapRef.current?.contains(e.relatedTarget as Node)) return;\n if (inlineList) setOpen(false);\n // came from a chip: nothing typed → show the chip again\n if (picked && !text) setSearching(false);\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\" && rows.length) {\n e.preventDefault();\n setOpen(true);\n setActive((a) => (a + 1) % rows.length);\n } else if (e.key === \"ArrowUp\" && rows.length) {\n e.preventDefault();\n setActive((a) => (a <= 0 ? rows.length - 1 : a - 1));\n } else if (e.key === \"Enter\") {\n e.preventDefault();\n if (listOpen && active >= 0 && rows[active]) choose(rows[active].target);\n else onEnter?.(withText(v, text, manualType ?? undefined));\n } else if (e.key === \"Escape\") {\n if (listOpen) {\n e.preventDefault();\n e.stopPropagation();\n setOpen(false);\n } else if (picked && !text && !startSearching) {\n e.preventDefault();\n e.stopPropagation();\n setSearching(false);\n } else if (onEscape) {\n e.preventDefault();\n e.stopPropagation();\n onEscape();\n }\n }\n }}\n placeholder={picked && !text ? picked.title : meta.placeholder}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"h-full min-w-0 flex-1 bg-transparent px-2 text-kit-sm text-kit-fg outline-none placeholder:text-kit-fg-3\"\n />\n {text ? (\n <IconButton label=\"Clear\" size=\"xs\" className=\"mr-1\" onMouseDown={(e) => e.preventDefault()} onClick={clear}>\n <IconX stroke={1.5} />\n </IconButton>\n ) : null}\n {type === \"file\" && MediaPicker ? (\n <IconButton\n label=\"Choose or upload a file\"\n size=\"xs\"\n className=\"mr-1 text-kit-fg-3\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n setOpen(false);\n setLibrary(true);\n }}\n >\n <IconFolderOpen stroke={1.5} />\n </IconButton>\n ) : null}\n </>\n )}\n </PopoverAnchor>\n </div>\n <PopoverContent\n keepFocus\n align=\"start\"\n side=\"bottom\"\n sideOffset={4}\n data-kit-link-list=\"\"\n className=\"w-[max(var(--anchor-width),280px)] max-w-[min(420px,calc(100vw-24px))] p-1\"\n >\n {list}\n </PopoverContent>\n </Popover>\n {inlineList && listOpen ? (\n <div className=\"rounded-kit-md border border-kit-line bg-kit-surface p-1 [&_[role=listbox]]:max-h-56\" onMouseDown={(e) => e.preventDefault()}>\n {list}\n </div>\n ) : null}\n {fileProblem ? (\n <p role=\"alert\" className=\"text-kit-xs text-kit-danger-fg\">\n {fileProblem}\n </p>\n ) : null}\n {/* File: the host's media library (search, folders, upload) is one click away; mounted only while open */}\n {library && MediaPicker ? (\n <MediaPicker\n open\n accept={[\"file\"]}\n onOpenChange={(o) => !o && setLibrary(false)}\n onPick={(a) => {\n if (!a[0]) return;\n const t = fileTarget(a[0]);\n if (\"problem\" in t) setFileProblem(t.problem);\n else choose(t);\n }}\n />\n ) : null}\n </div>\n );\n}\n\n/* ── Shared options (subject · open in new tab · rel) ───────────────── */\nexport function LinkOptions({ v, onChange, compact, disabled }: { v: LinkValue; onChange: (v: LinkValue) => void; compact?: boolean; disabled?: boolean }) {\n const tabId = React.useId();\n return (\n <div className={cn(\"flex flex-col\", compact ? \"gap-2\" : \"gap-2.5\")}>\n {v.type === \"email\" ? (\n <label className=\"flex items-center justify-between gap-3\">\n <span className=\"text-kit-xs text-kit-fg-2\">Subject</span>\n <Input size=\"sm\" value={v.subject ?? \"\"} onChange={(e) => onChange({ ...v, subject: e.target.value })} placeholder=\"Wholesale inquiry\" className=\"max-w-52\" />\n </label>\n ) : null}\n <label htmlFor={tabId} className=\"flex min-h-7 items-center justify-between gap-3\">\n <span className=\"text-kit-xs text-kit-fg-2\">Open in new tab</span>\n <Switch disabled={disabled} id={tabId} size=\"sm\" checked={!!v.newTab} onCheckedChange={(c) => onChange({ ...v, newTab: c, target: undefined })} />\n </label>\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-kit-xs text-kit-fg-2\">Rel</span>\n <Select disabled={disabled} aria-label=\"Rel\" size=\"sm\" className=\"w-[168px]\" value={v.rel ?? \"follow\"} onValueChange={(r) => onChange({ ...v, rel: r as LinkRel })} options={REL_ITEMS} />\n </div>\n </div>\n );\n}\n\n/* ── The link element ───────────────────────────────────────────────\n * CPO D48 + D57: the ONE way to edit a link, wherever a link is edited: Type (dropdown) → the target for that type\n * (results appear only once you focus or type, in the flow below the input, never over the panel; File adds the media\n * library) → the error in plain words when it can't be saved → Section on the picked page → the options as plain rows\n * (new tab, rel, subject). Hosts wrap it: the link panel (LinkPopoverBody), the button screen. Controlled: the host owns\n * the value; remount (key) to start over.\n */\nexport function LinkForm({\n value,\n onChange,\n onEnter,\n hideOptions,\n types,\n autoFocus,\n readOnly,\n className,\n}: {\n value: LinkValue;\n onChange: (v: LinkValue) => void;\n /** Enter in the target with a value that can be saved */\n onEnter?: (v: LinkValue) => void;\n /** string-only values: no new tab / rel */\n hideOptions?: boolean;\n /** the link types this place allows. Default: all */\n types?: LinkType[];\n /** focus the Type control on open (D48: never the search) */\n autoFocus?: boolean;\n /** the lens can't edit the link: every control is disabled */\n readOnly?: boolean;\n className?: string;\n}) {\n const v = normLink(value);\n const { MediaPicker } = useKitServices();\n const allowed = LINK_TYPES.filter((t) => (!types || types.includes(t.type)) && (t.type !== \"file\" || MediaPicker || v.type === \"file\"));\n const [kind, setKind] = React.useState<LinkType>(() => {\n const k = v.type === \"entry\" && hasLink(v) ? \"page\" : v.type ?? \"page\";\n return allowed.some((t) => t.type === k) ? k : allowed[0]?.type ?? \"page\";\n });\n const [resetKey, setResetKey] = React.useState(0);\n const [touched, setTouched] = React.useState(false);\n const { targets } = useLinkTargets();\n const anchors = findTarget(targets, v)?.anchors;\n const typeId = React.useId();\n const targetId = React.useId();\n const errId = React.useId();\n const problem = touched ? linkProblem(v) : undefined;\n // the type select follows what the target turned out to be (a picked CMS item, a pasted URL) while \"Page\" is searching\n const shownType: LinkType = kind === \"page\" && hasLink(v) ? v.type ?? \"page\" : kind;\n React.useEffect(() => {\n if (autoFocus) requestAnimationFrame(() => document.getElementById(typeId)?.focus({ preventScroll: true }));\n }, [autoFocus, typeId]);\n const changeType = (t: LinkType) => {\n setKind(t);\n setTouched(false);\n onChange({ ...withText(v, \"\", t === \"page\" ? undefined : t), href: \"\", type: t, anchor: undefined });\n setResetKey((k) => k + 1);\n requestAnimationFrame(() => document.getElementById(targetId)?.focus());\n };\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-3\", className)}>\n <div className=\"flex items-center justify-between gap-3\">\n <label htmlFor={typeId} className=\"text-kit-xs text-kit-fg-2\">\n Type\n </label>\n <Select disabled={readOnly} id={typeId} size=\"sm\" className=\"w-[180px]\" value={shownType} onValueChange={(t) => changeType(t as LinkType)} options={allowed.map((t) => ({ value: t.type, label: t.label, icon: t.icon }))} />\n </div>\n <div\n className=\"flex flex-col gap-1.5\"\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node)) setTouched(true);\n }}\n >\n <label htmlFor={targetId} className=\"text-kit-xs text-kit-fg-2\">\n {typeMeta(kind).target}\n </label>\n <LinkPicker\n key={resetKey}\n id={targetId}\n size=\"sm\"\n value={v}\n onChange={onChange}\n onPick={() => setTouched(true)}\n onEnter={(n) => {\n setTouched(true);\n if (!linkProblem(n)) onEnter?.(n);\n }}\n lockedType={kind === \"page\" ? undefined : kind}\n inlineList\n types={types}\n invalid={!!problem}\n aria-describedby={problem ? errId : undefined}\n aria-label={typeMeta(kind).target}\n />\n {problem ? (\n <p id={errId} role=\"alert\" className=\"text-kit-xs text-kit-danger-fg\">\n {problem}\n </p>\n ) : null}\n </div>\n {anchors?.length ? (\n <div className=\"flex items-center justify-between gap-3\">\n <span className=\"text-kit-xs text-kit-fg-2\">Section</span>\n <Select disabled={readOnly} aria-label=\"Section\"\n size=\"sm\"\n className=\"w-[180px]\"\n value={v.anchor ?? \"none\"}\n onValueChange={(a) => onChange({ ...v, anchor: a })}\n options={[{ value: \"none\", label: \"Top of page\" }, ...anchors.map((a) => ({ value: a, label: a }))]}\n />\n </div>\n ) : null}\n {hideOptions ? null : <LinkOptions v={v} onChange={onChange} compact disabled={readOnly} />}\n </div>\n );\n}\n\n/* ── The link panel ─────────────────────────────────────────────────\n * What it links to now → the link element (LinkForm) → Remove link · Cancel · Apply (Apply only when something changed\n * and the link can be saved). Esc closes the results first, then the panel.\n */\nexport function LinkPopoverBody({\n initial,\n onSave,\n onDetach,\n onCancel,\n hideOptions,\n types,\n}: {\n initial: LinkValue;\n onSave: (v: LinkValue) => void;\n onDetach?: () => void;\n onCancel?: () => void;\n /** string-only fields: no new tab / rel */\n hideOptions?: boolean;\n /** the link types this place allows. Default: all */\n types?: LinkType[];\n}) {\n const start = normLink(initial);\n const [v, setV] = React.useState<LinkValue>(start);\n const { targets } = useLinkTargets();\n const startTarget = findTarget(targets, start);\n const fin = (x: LinkValue) => {\n const f = finalizeLink(x);\n return f ? JSON.stringify(storedLink(f)) : \"\";\n };\n const changed = fin(v) !== fin(start);\n const ok = hasLink(v) && !linkProblem(v);\n const apply = (n = v) => {\n const out = finalizeLink(n);\n if (out && hasLink(out) && !linkProblem(out)) onSave(out);\n };\n return (\n <form\n className=\"flex flex-col gap-3\"\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n apply();\n }}\n >\n <div className=\"flex min-w-0 flex-col gap-1\">\n <span className=\"text-kit-sm font-medium text-kit-fg\">Link</span>\n {hasLink(start) ? (\n <span className=\"flex min-w-0 text-kit-fg-2\">\n <LinkLine v={start} target={startTarget} />\n </span>\n ) : (\n <span className=\"text-kit-xs text-kit-fg-3\">No link yet</span>\n )}\n </div>\n <LinkForm value={v} onChange={setV} onEnter={(n) => apply(n)} hideOptions={hideOptions} types={types} autoFocus />\n <div className=\"flex items-center gap-2 border-t border-kit-line pt-2.5\">\n {onDetach ? (\n <Button type=\"button\" size=\"xs\" variant=\"danger-ghost\" onClick={onDetach}>\n Remove link\n </Button>\n ) : null}\n <span className=\"flex-1\" />\n {onCancel ? (\n <Button type=\"button\" size=\"xs\" variant=\"ghost\" onClick={onCancel}>\n Cancel\n </Button>\n ) : null}\n <Button type=\"submit\" size=\"xs\" variant=\"primary\" disabled={!changed || !ok}>\n Apply\n </Button>\n </div>\n </form>\n );\n}\n\n/* ── Quick edit: the link row turns into the picker in place ───────── */\nexport function LinkQuickEdit({\n value,\n onCommit,\n onDone,\n ariaLabel,\n size,\n bare,\n types,\n}: {\n value: LinkValue;\n /** null = cleared */\n onCommit: (v: LinkValue | null) => void;\n onDone: () => void;\n ariaLabel: string;\n size?: \"sm\" | \"md\";\n bare?: boolean;\n types?: LinkType[];\n}) {\n const [draft, setDraft] = React.useState(value);\n const [problem, setProblem] = React.useState<string>();\n const done = React.useRef(false);\n const ref = React.useRef<HTMLDivElement>(null);\n const errId = React.useId();\n const commit = (n: LinkValue, strict = true) => {\n if (done.current) return;\n if (hasLink(n) && strict && linkProblem(n)) return setProblem(linkProblem(n));\n done.current = true;\n if (!hasLink(n)) onCommit(null);\n else {\n const out = finalizeLink(n);\n // a script link is dropped, never written (finalizeLink refuses it)\n if (out) onCommit(out);\n }\n onDone();\n };\n return (\n <div\n ref={ref}\n className=\"flex min-w-0 flex-col gap-1\"\n onBlur={(e) => {\n const next = e.relatedTarget as HTMLElement | null;\n if (libraryOpen || (next && (ref.current?.contains(next) || next.closest?.(`[${LIST_ATTR}],[role=menu]`)))) return;\n // focus left the editor: keep what was typed (nothing changed → nothing written)\n window.setTimeout(() => {\n if (libraryOpen || done.current || ref.current?.contains(document.activeElement)) return;\n if (hrefOf(draft) === hrefOf(value) && draft.pageId === value.pageId && draft.entryId === value.entryId) {\n done.current = true;\n onDone();\n } else commit(draft, false);\n }, 0);\n }}\n >\n <LinkPicker\n value={draft}\n onChange={(n) => {\n setDraft(n);\n setProblem(undefined);\n }}\n onPick={(n) => commit(n)}\n onEnter={(n) => commit(n)}\n onEscape={() => {\n done.current = true;\n onDone();\n }}\n autoFocus\n startSearching\n aria-label={ariaLabel}\n size={size}\n bare={bare}\n types={types}\n invalid={!!problem}\n aria-describedby={problem ? errId : undefined}\n />\n {problem ? (\n <p id={errId} role=\"alert\" className={cn(\"text-kit-xs text-kit-danger-fg\", bare && \"px-2.5 pb-1.5\")}>\n {problem}\n </p>\n ) : null}\n </div>\n );\n}\n\n/* ── Link field: one bordered row; click edits in place, the sliders icon opens the link panel ── */\nexport interface LinkFieldProps {\n /** a LinkValue or a plain href string */\n value: unknown;\n /** null = cleared (object shape); \"\" = cleared (string shape) */\n onChange: (v: LinkValue | string | null) => void;\n /** \"string\": the value is the href alone. New tab and rel need the object shape, so they hide. */\n valueShape?: \"string\" | \"object\";\n id?: string;\n \"aria-label\": string;\n readOnly?: boolean;\n size?: \"sm\" | \"md\";\n /** the link types this place allows. Default: all */\n types?: LinkType[];\n invalid?: boolean;\n placeholder?: string;\n className?: string;\n}\nexport function LinkField({ value, onChange: write, valueShape, id: idProp, \"aria-label\": label, readOnly, size = \"sm\", types, invalid, placeholder, className }: LinkFieldProps) {\n const v = normLink(value);\n const stringOnly = valueShape === \"string\";\n const onChange = (n: LinkValue | null) => write(stringOnly ? (n ? hrefOf(n) : \"\") : n ? storedLink(n, value) : null);\n const autoId = React.useId();\n const id = idProp ?? autoId;\n const [editing, setEditing] = React.useState(false);\n const [open, setOpen] = React.useState(false);\n const { targets } = useLinkTargets();\n const target = findTarget(targets, v);\n const has = hasLink(v);\n if (editing && !readOnly)\n return (\n <LinkQuickEdit\n value={v}\n ariaLabel={label}\n size={size}\n types={types}\n onCommit={onChange}\n onDone={() => {\n setEditing(false);\n requestAnimationFrame(() => document.getElementById(id)?.focus({ preventScroll: true }));\n }}\n />\n );\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverAnchor\n data-kit-link-field=\"\"\n className={cn(\n \"group/link relative flex min-w-0 items-center rounded-kit-md border border-kit-field-border bg-kit-field-bg shadow-kit-field transition-colors hover:border-kit-field-border-hover\",\n size === \"md\" ? \"h-9\" : \"h-8\",\n readOnly && \"hover:border-kit-field-border\",\n invalid && \"border-[var(--kit-field-invalid)]\",\n className,\n )}\n >\n <button\n id={id}\n type=\"button\"\n disabled={readOnly}\n onClick={() => setEditing(true)}\n aria-label={has ? `${label}: ${describeLink(v, target).primary}. Edit link` : `Add ${label.toLowerCase()}`}\n aria-invalid={invalid || undefined}\n className=\"flex h-full min-w-0 flex-1 items-center px-2.5 text-left outline-none disabled:cursor-default\"\n >\n <LinkLine v={v} target={target} placeholder={placeholder} />\n </button>\n {readOnly ? null : (\n <span className=\"mr-1 flex shrink-0 items-center gap-0.5\">\n <Tooltip content=\"Link options\">\n <PopoverTrigger\n render={\n <IconButton label=\"Link options\" tooltip={false} size=\"xs\" className=\"text-kit-fg-3\">\n <IconAdjustmentsHorizontal stroke={1.5} />\n </IconButton>\n }\n />\n </Tooltip>\n {has ? (\n <IconButton\n label={`Clear ${label.toLowerCase()}`}\n size=\"xs\"\n className=\"hidden text-kit-fg-3 group-hover/link:inline-flex group-focus-within/link:inline-flex [@media(pointer:coarse)]:inline-flex\"\n onClick={() => onChange(null)}\n >\n <IconX stroke={1.5} />\n </IconButton>\n ) : null}\n </span>\n )}\n </PopoverAnchor>\n <PopoverContent className=\"w-[340px] p-3\" align=\"start\">\n <LinkPopoverBody\n initial={v}\n hideOptions={stringOnly}\n types={types}\n onSave={(n) => {\n onChange(n);\n setOpen(false);\n }}\n onDetach={\n has\n ? () => {\n onChange(null);\n setOpen(false);\n }\n : undefined\n }\n onCancel={() => setOpen(false)}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\n/**\n * The shape a link field writes: the shape its value already has (a string stays a string, an object an object), and\n * for an empty field `field.valueShape`, else the string prod stores by default.\n */\nexport function linkShapeOf(value: unknown, valueShape?: \"string\" | \"object\"): \"string\" | \"object\" {\n if (isObj(value)) return \"object\";\n if (typeof value === \"string\" && value !== \"\") return \"string\";\n return valueShape ?? \"string\";\n}\n\n/** The Block Kit `link` field: the LinkField above, sized for the form it sits in. */\nexport function LinkControl({ value, onChange, readOnly, id, field, invalid }: ControlProps) {\n const { variant } = useKitEnv();\n return (\n <LinkField\n id={id}\n value={value}\n onChange={onChange}\n valueShape={linkShapeOf(value, field.valueShape)}\n aria-label={field.title}\n readOnly={readOnly}\n size={variant === \"document\" ? \"md\" : \"sm\"}\n invalid={invalid}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CONTROLS } from "../engine/kit-field.js";
|
|
2
|
+
import { LocationControl } from "./location.js";
|
|
3
|
+
//#region src/kit/controls/location-register.ts
|
|
4
|
+
/** Lane C3: the geopoint (prod `location`) field in the engine's dispatch table (one line per type; merge by line). */
|
|
5
|
+
CONTROLS.geopoint = LocationControl;
|
|
6
|
+
//#endregion
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=location-register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location-register.js","names":[],"sources":["../../src/kit/controls/location-register.ts"],"sourcesContent":["/** Lane C3: the geopoint (prod `location`) field in the engine's dispatch table (one line per type; merge by line). */\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { LocationControl } from \"./location\";\n\nCONTROLS.geopoint = LocationControl;\n"],"mappings":";;;;AAIA,SAAS,WAAW"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ControlProps } from "../types";
|
|
2
|
+
interface Draft {
|
|
3
|
+
lat: string;
|
|
4
|
+
lng: string;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
/** The value a draft writes, or the reason it can't be written yet. */
|
|
8
|
+
export declare function locationFromDraft(d: Draft, prev: unknown): {
|
|
9
|
+
ok: true;
|
|
10
|
+
value: Record<string, unknown> | null;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function LocationControl({ field, value, onChange, readOnly, id, invalid }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { isObj } from "../lib/path.js";
|
|
3
|
+
import { Input } from "../ui/input.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { IconExternalLink, IconMapPin } from "@tabler/icons-react";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/kit/controls/location.tsx
|
|
8
|
+
/**
|
|
9
|
+
* LOCATION — the geopoint field (DESIGN 8.21), V2 GeoControl fitted to what prod stores.
|
|
10
|
+
*
|
|
11
|
+
* Value (backend reference-validation `location`, the classic LocationField): `{ lat, lng, label? }`, lat −90…90 and
|
|
12
|
+
* lng −180…180, finite numbers; null when empty. Keys the stored object carries beyond those are kept.
|
|
13
|
+
*
|
|
14
|
+
* A coordinate is written only when it is whole: both numbers, in range. Until then the field says what is missing
|
|
15
|
+
* ("Add the longitude too") and keeps the stored value, because the backend refuses half a coordinate. Emptying all
|
|
16
|
+
* three boxes clears the value. Pasting "44.0582, -121.3153" into either box fills both.
|
|
17
|
+
*
|
|
18
|
+
* The card above the inputs shows the pin and the coordinates, with a link that opens them on OpenStreetMap; it
|
|
19
|
+
* draws no map tiles (no vendor, key or bundle).
|
|
20
|
+
*/
|
|
21
|
+
var num = (v) => typeof v === "number" && Number.isFinite(v) ? String(v) : "";
|
|
22
|
+
var draftOf = (v) => isObj(v) ? {
|
|
23
|
+
lat: num(v.lat),
|
|
24
|
+
lng: num(v.lng),
|
|
25
|
+
label: typeof v.label === "string" ? v.label : ""
|
|
26
|
+
} : {
|
|
27
|
+
lat: "",
|
|
28
|
+
lng: "",
|
|
29
|
+
label: ""
|
|
30
|
+
};
|
|
31
|
+
var PAIR = /^\s*(-?\d+(?:\.\d+)?)\s*[,;\s]\s*(-?\d+(?:\.\d+)?)\s*$/;
|
|
32
|
+
/** The value a draft writes, or the reason it can't be written yet. */
|
|
33
|
+
function locationFromDraft(d, prev) {
|
|
34
|
+
const lat = d.lat.trim();
|
|
35
|
+
const lng = d.lng.trim();
|
|
36
|
+
const label = d.label.trim();
|
|
37
|
+
if (!lat && !lng && !label) return {
|
|
38
|
+
ok: true,
|
|
39
|
+
value: null
|
|
40
|
+
};
|
|
41
|
+
if (!lat || !lng) return {
|
|
42
|
+
ok: false,
|
|
43
|
+
reason: !lat && !lng ? "Add a latitude and a longitude to save this location." : !lat ? "Add the latitude too: a location needs both." : "Add the longitude too: a location needs both."
|
|
44
|
+
};
|
|
45
|
+
const la = Number(lat);
|
|
46
|
+
const lo = Number(lng);
|
|
47
|
+
if (!Number.isFinite(la) || Math.abs(la) > 90) return {
|
|
48
|
+
ok: false,
|
|
49
|
+
reason: "Latitude must be a number from −90 to 90."
|
|
50
|
+
};
|
|
51
|
+
if (!Number.isFinite(lo) || Math.abs(lo) > 180) return {
|
|
52
|
+
ok: false,
|
|
53
|
+
reason: "Longitude must be a number from −180 to 180."
|
|
54
|
+
};
|
|
55
|
+
const out = {
|
|
56
|
+
...isObj(prev) ? prev : {},
|
|
57
|
+
lat: la,
|
|
58
|
+
lng: lo
|
|
59
|
+
};
|
|
60
|
+
if (label) out.label = label;
|
|
61
|
+
else delete out.label;
|
|
62
|
+
return {
|
|
63
|
+
ok: true,
|
|
64
|
+
value: out
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function LocationControl({ field, value, onChange, readOnly, id, invalid }) {
|
|
68
|
+
const [draft, setDraft] = React.useState(() => draftOf(value));
|
|
69
|
+
const [seen, setSeen] = React.useState(value);
|
|
70
|
+
const [mine, setMine] = React.useState(void 0);
|
|
71
|
+
if (value !== seen) {
|
|
72
|
+
setSeen(value);
|
|
73
|
+
if (value !== mine) setDraft(draftOf(value));
|
|
74
|
+
}
|
|
75
|
+
const result = locationFromDraft(draft, value);
|
|
76
|
+
const reasonId = `${id}-reason`;
|
|
77
|
+
const update = (patch) => {
|
|
78
|
+
const next = {
|
|
79
|
+
...draft,
|
|
80
|
+
...patch
|
|
81
|
+
};
|
|
82
|
+
setDraft(next);
|
|
83
|
+
const r = locationFromDraft(next, value);
|
|
84
|
+
if (!r.ok) return;
|
|
85
|
+
if (JSON.stringify(r.value) === JSON.stringify(value ?? null)) return;
|
|
86
|
+
setMine(r.value);
|
|
87
|
+
onChange(r.value);
|
|
88
|
+
};
|
|
89
|
+
const coordinate = (key) => (e) => {
|
|
90
|
+
const pair = PAIR.exec(e.target.value);
|
|
91
|
+
update(pair ? {
|
|
92
|
+
lat: pair[1],
|
|
93
|
+
lng: pair[2]
|
|
94
|
+
} : { [key]: e.target.value });
|
|
95
|
+
};
|
|
96
|
+
const shown = isObj(value) && typeof value.lat === "number" && typeof value.lng === "number" ? {
|
|
97
|
+
lat: value.lat,
|
|
98
|
+
lng: value.lng
|
|
99
|
+
} : null;
|
|
100
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
101
|
+
className: cn("overflow-hidden rounded-kit-lg border", invalid ? "border-[var(--kit-field-invalid)]" : "border-kit-line"),
|
|
102
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
103
|
+
className: "relative h-28 overflow-hidden bg-kit-subtle",
|
|
104
|
+
style: {
|
|
105
|
+
backgroundImage: "linear-gradient(var(--kit-line-subtle) 1px, transparent 1px), linear-gradient(90deg, var(--kit-line-subtle) 1px, transparent 1px)",
|
|
106
|
+
backgroundSize: "16px 16px"
|
|
107
|
+
},
|
|
108
|
+
children: shown ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
109
|
+
className: "absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-full flex-col items-center",
|
|
110
|
+
"aria-hidden": true,
|
|
111
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
112
|
+
className: "flex size-7 items-center justify-center rounded-full bg-kit-inverse text-kit-fg-inverse shadow-kit-md",
|
|
113
|
+
children: /* @__PURE__ */ jsx(IconMapPin, {
|
|
114
|
+
className: "size-4",
|
|
115
|
+
stroke: 1.5
|
|
116
|
+
})
|
|
117
|
+
}), /* @__PURE__ */ jsx("span", { className: "size-2 -translate-y-0.5 rotate-45 bg-kit-inverse" })]
|
|
118
|
+
}), /* @__PURE__ */ jsxs("a", {
|
|
119
|
+
href: `https://www.openstreetmap.org/?mlat=${shown.lat}&mlon=${shown.lng}#map=15/${shown.lat}/${shown.lng}`,
|
|
120
|
+
target: "_blank",
|
|
121
|
+
rel: "noreferrer noopener",
|
|
122
|
+
className: "absolute bottom-2 right-2 flex items-center gap-1 rounded-kit-md bg-kit-surface/90 px-1.5 py-0.5 font-kit-mono text-kit-2xs tabular-nums text-kit-fg-2 shadow-kit-xs outline-none hover:text-kit-fg focus-visible:outline-2 focus-visible:outline-kit-focus-ring",
|
|
123
|
+
"aria-label": `Open ${shown.lat.toFixed(4)}, ${shown.lng.toFixed(4)} on OpenStreetMap (new tab)`,
|
|
124
|
+
children: [
|
|
125
|
+
shown.lat.toFixed(4),
|
|
126
|
+
", ",
|
|
127
|
+
shown.lng.toFixed(4),
|
|
128
|
+
/* @__PURE__ */ jsx(IconExternalLink, {
|
|
129
|
+
className: "size-3",
|
|
130
|
+
stroke: 1.5,
|
|
131
|
+
"aria-hidden": true
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
})] }) : /* @__PURE__ */ jsx("p", {
|
|
135
|
+
className: "absolute inset-0 flex items-center justify-center text-kit-xs text-kit-fg-3",
|
|
136
|
+
children: "No coordinates yet"
|
|
137
|
+
})
|
|
138
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
139
|
+
className: "flex flex-col gap-2 p-2",
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ jsx(Input, {
|
|
142
|
+
id,
|
|
143
|
+
value: draft.label,
|
|
144
|
+
readOnly,
|
|
145
|
+
placeholder: "Label, e.g. Head office",
|
|
146
|
+
"aria-label": `${field.title} label`,
|
|
147
|
+
leading: /* @__PURE__ */ jsx(IconMapPin, { stroke: 1.5 }),
|
|
148
|
+
onChange: (e) => update({ label: e.target.value })
|
|
149
|
+
}),
|
|
150
|
+
/* @__PURE__ */ jsxs("div", {
|
|
151
|
+
className: "grid grid-cols-2 gap-2",
|
|
152
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
153
|
+
id: `${id}-lat`,
|
|
154
|
+
size: "sm",
|
|
155
|
+
inputMode: "decimal",
|
|
156
|
+
value: draft.lat,
|
|
157
|
+
readOnly,
|
|
158
|
+
"aria-label": `${field.title} latitude`,
|
|
159
|
+
"aria-invalid": !result.ok && /latitude/i.test(result.reason) || void 0,
|
|
160
|
+
"aria-describedby": !result.ok ? reasonId : void 0,
|
|
161
|
+
placeholder: "−90 to 90",
|
|
162
|
+
onChange: coordinate("lat"),
|
|
163
|
+
leading: /* @__PURE__ */ jsx("span", {
|
|
164
|
+
className: "text-kit-2xs",
|
|
165
|
+
children: "Lat"
|
|
166
|
+
})
|
|
167
|
+
}), /* @__PURE__ */ jsx(Input, {
|
|
168
|
+
id: `${id}-lng`,
|
|
169
|
+
size: "sm",
|
|
170
|
+
inputMode: "decimal",
|
|
171
|
+
value: draft.lng,
|
|
172
|
+
readOnly,
|
|
173
|
+
"aria-label": `${field.title} longitude`,
|
|
174
|
+
"aria-invalid": !result.ok && /longitude/i.test(result.reason) || void 0,
|
|
175
|
+
"aria-describedby": !result.ok ? reasonId : void 0,
|
|
176
|
+
placeholder: "−180 to 180",
|
|
177
|
+
onChange: coordinate("lng"),
|
|
178
|
+
leading: /* @__PURE__ */ jsx("span", {
|
|
179
|
+
className: "text-kit-2xs",
|
|
180
|
+
children: "Long"
|
|
181
|
+
})
|
|
182
|
+
})]
|
|
183
|
+
}),
|
|
184
|
+
!result.ok ? /* @__PURE__ */ jsx("p", {
|
|
185
|
+
id: reasonId,
|
|
186
|
+
role: "status",
|
|
187
|
+
className: "text-kit-xs text-kit-warning-fg",
|
|
188
|
+
children: result.reason
|
|
189
|
+
}) : null
|
|
190
|
+
]
|
|
191
|
+
})]
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
export { LocationControl };
|
|
196
|
+
|
|
197
|
+
//# sourceMappingURL=location.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"location.js","names":[],"sources":["../../src/kit/controls/location.tsx"],"sourcesContent":["/**\n * LOCATION — the geopoint field (DESIGN 8.21), V2 GeoControl fitted to what prod stores.\n *\n * Value (backend reference-validation `location`, the classic LocationField): `{ lat, lng, label? }`, lat −90…90 and\n * lng −180…180, finite numbers; null when empty. Keys the stored object carries beyond those are kept.\n *\n * A coordinate is written only when it is whole: both numbers, in range. Until then the field says what is missing\n * (\"Add the longitude too\") and keeps the stored value, because the backend refuses half a coordinate. Emptying all\n * three boxes clears the value. Pasting \"44.0582, -121.3153\" into either box fills both.\n *\n * The card above the inputs shows the pin and the coordinates, with a link that opens them on OpenStreetMap; it\n * draws no map tiles (no vendor, key or bundle).\n */\nimport * as React from \"react\";\nimport { IconExternalLink, IconMapPin } from \"@tabler/icons-react\";\nimport { cn } from \"../lib/cn\";\nimport { isObj } from \"../lib/path\";\nimport type { ControlProps } from \"../types\";\nimport { Input } from \"../ui/input\";\n\ninterface Draft {\n lat: string;\n lng: string;\n label: string;\n}\nconst num = (v: unknown) => (typeof v === \"number\" && Number.isFinite(v) ? String(v) : \"\");\nconst draftOf = (v: unknown): Draft => (isObj(v) ? { lat: num(v.lat), lng: num(v.lng), label: typeof v.label === \"string\" ? v.label : \"\" } : { lat: \"\", lng: \"\", label: \"\" });\nconst PAIR = /^\\s*(-?\\d+(?:\\.\\d+)?)\\s*[,;\\s]\\s*(-?\\d+(?:\\.\\d+)?)\\s*$/;\n\n/** The value a draft writes, or the reason it can't be written yet. */\nexport function locationFromDraft(d: Draft, prev: unknown): { ok: true; value: Record<string, unknown> | null } | { ok: false; reason: string } {\n const lat = d.lat.trim();\n const lng = d.lng.trim();\n const label = d.label.trim();\n if (!lat && !lng && !label) return { ok: true, value: null };\n if (!lat || !lng) return { ok: false, reason: !lat && !lng ? \"Add a latitude and a longitude to save this location.\" : !lat ? \"Add the latitude too: a location needs both.\" : \"Add the longitude too: a location needs both.\" };\n const la = Number(lat);\n const lo = Number(lng);\n if (!Number.isFinite(la) || Math.abs(la) > 90) return { ok: false, reason: \"Latitude must be a number from −90 to 90.\" };\n if (!Number.isFinite(lo) || Math.abs(lo) > 180) return { ok: false, reason: \"Longitude must be a number from −180 to 180.\" };\n const out: Record<string, unknown> = { ...(isObj(prev) ? prev : {}), lat: la, lng: lo };\n if (label) out.label = label;\n else delete out.label;\n return { ok: true, value: out };\n}\n\nexport function LocationControl({ field, value, onChange, readOnly, id, invalid }: ControlProps) {\n const [draft, setDraft] = React.useState<Draft>(() => draftOf(value));\n const [seen, setSeen] = React.useState(value);\n const [mine, setMine] = React.useState<unknown>(undefined);\n // a value set from elsewhere (undo, another editor) replaces the draft; our own writes keep what the author typed\n if (value !== seen) {\n setSeen(value);\n if (value !== mine) setDraft(draftOf(value));\n }\n const result = locationFromDraft(draft, value);\n const reasonId = `${id}-reason`;\n\n const update = (patch: Partial<Draft>) => {\n const next = { ...draft, ...patch };\n setDraft(next);\n const r = locationFromDraft(next, value);\n if (!r.ok) return;\n const same = JSON.stringify(r.value) === JSON.stringify(value ?? null);\n if (same) return;\n setMine(r.value);\n onChange(r.value);\n };\n const coordinate = (key: \"lat\" | \"lng\") => (e: React.ChangeEvent<HTMLInputElement>) => {\n const pair = PAIR.exec(e.target.value);\n update(pair ? { lat: pair[1], lng: pair[2] } : ({ [key]: e.target.value } as Partial<Draft>));\n };\n\n const shown = isObj(value) && typeof value.lat === \"number\" && typeof value.lng === \"number\" ? { lat: value.lat, lng: value.lng } : null;\n return (\n <div className={cn(\"overflow-hidden rounded-kit-lg border\", invalid ? \"border-[var(--kit-field-invalid)]\" : \"border-kit-line\")}>\n <div\n className=\"relative h-28 overflow-hidden bg-kit-subtle\"\n style={{ backgroundImage: \"linear-gradient(var(--kit-line-subtle) 1px, transparent 1px), linear-gradient(90deg, var(--kit-line-subtle) 1px, transparent 1px)\", backgroundSize: \"16px 16px\" }}\n >\n {shown ? (\n <>\n <div className=\"absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-full flex-col items-center\" aria-hidden>\n <span className=\"flex size-7 items-center justify-center rounded-full bg-kit-inverse text-kit-fg-inverse shadow-kit-md\">\n <IconMapPin className=\"size-4\" stroke={1.5} />\n </span>\n <span className=\"size-2 -translate-y-0.5 rotate-45 bg-kit-inverse\" />\n </div>\n <a\n href={`https://www.openstreetmap.org/?mlat=${shown.lat}&mlon=${shown.lng}#map=15/${shown.lat}/${shown.lng}`}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"absolute bottom-2 right-2 flex items-center gap-1 rounded-kit-md bg-kit-surface/90 px-1.5 py-0.5 font-kit-mono text-kit-2xs tabular-nums text-kit-fg-2 shadow-kit-xs outline-none hover:text-kit-fg focus-visible:outline-2 focus-visible:outline-kit-focus-ring\"\n aria-label={`Open ${shown.lat.toFixed(4)}, ${shown.lng.toFixed(4)} on OpenStreetMap (new tab)`}\n >\n {shown.lat.toFixed(4)}, {shown.lng.toFixed(4)}\n <IconExternalLink className=\"size-3\" stroke={1.5} aria-hidden />\n </a>\n </>\n ) : (\n <p className=\"absolute inset-0 flex items-center justify-center text-kit-xs text-kit-fg-3\">No coordinates yet</p>\n )}\n </div>\n <div className=\"flex flex-col gap-2 p-2\">\n <Input\n id={id}\n value={draft.label}\n readOnly={readOnly}\n placeholder=\"Label, e.g. Head office\"\n aria-label={`${field.title} label`}\n leading={<IconMapPin stroke={1.5} />}\n onChange={(e) => update({ label: e.target.value })}\n />\n <div className=\"grid grid-cols-2 gap-2\">\n <Input\n id={`${id}-lat`}\n size=\"sm\"\n inputMode=\"decimal\"\n value={draft.lat}\n readOnly={readOnly}\n aria-label={`${field.title} latitude`}\n aria-invalid={(!result.ok && /latitude/i.test(result.reason)) || undefined}\n aria-describedby={!result.ok ? reasonId : undefined}\n placeholder=\"−90 to 90\"\n onChange={coordinate(\"lat\")}\n leading={<span className=\"text-kit-2xs\">Lat</span>}\n />\n <Input\n id={`${id}-lng`}\n size=\"sm\"\n inputMode=\"decimal\"\n value={draft.lng}\n readOnly={readOnly}\n aria-label={`${field.title} longitude`}\n aria-invalid={(!result.ok && /longitude/i.test(result.reason)) || undefined}\n aria-describedby={!result.ok ? reasonId : undefined}\n placeholder=\"−180 to 180\"\n onChange={coordinate(\"lng\")}\n leading={<span className=\"text-kit-2xs\">Long</span>}\n />\n </div>\n {!result.ok ? (\n <p id={reasonId} role=\"status\" className=\"text-kit-xs text-kit-warning-fg\">\n {result.reason}\n </p>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyBA,IAAM,OAAO,MAAgB,OAAO,MAAM,YAAY,OAAO,SAAS,EAAE,GAAG,OAAO,EAAE,GAAG;AACvF,IAAM,WAAW,MAAuB,MAAM,EAAE,GAAG;CAAE,KAAK,IAAI,EAAE,IAAI;CAAE,KAAK,IAAI,EAAE,IAAI;CAAE,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ;CAAI,GAAG;CAAE,KAAK;CAAI,KAAK;CAAI,OAAO;CAAI;AAC5K,IAAM,OAAO;;AAGb,SAAgB,kBAAkB,GAAU,MAAoG;CAC9I,MAAM,MAAM,EAAE,IAAI,MAAM;CACxB,MAAM,MAAM,EAAE,IAAI,MAAM;CACxB,MAAM,QAAQ,EAAE,MAAM,MAAM;AAC5B,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAO,QAAO;EAAE,IAAI;EAAM,OAAO;EAAM;AAC5D,KAAI,CAAC,OAAO,CAAC,IAAK,QAAO;EAAE,IAAI;EAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,0DAA0D,CAAC,MAAM,iDAAiD;EAAiD;CAChO,MAAM,KAAK,OAAO,IAAI;CACtB,MAAM,KAAK,OAAO,IAAI;AACtB,KAAI,CAAC,OAAO,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,GAAG,GAAI,QAAO;EAAE,IAAI;EAAO,QAAQ;EAA6C;AACxH,KAAI,CAAC,OAAO,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,GAAG,IAAK,QAAO;EAAE,IAAI;EAAO,QAAQ;EAAgD;CAC5H,MAAM,MAA+B;EAAE,GAAI,MAAM,KAAK,GAAG,OAAO,EAAE;EAAG,KAAK;EAAI,KAAK;EAAI;AACvF,KAAI,MAAO,KAAI,QAAQ;KAClB,QAAO,IAAI;AAChB,QAAO;EAAE,IAAI;EAAM,OAAO;EAAK;;AAGjC,SAAgB,gBAAgB,EAAE,OAAO,OAAO,UAAU,UAAU,IAAI,WAAyB;CAC/F,MAAM,CAAC,OAAO,YAAY,MAAM,eAAsB,QAAQ,MAAM,CAAC;CACrE,MAAM,CAAC,MAAM,WAAW,MAAM,SAAS,MAAM;CAC7C,MAAM,CAAC,MAAM,WAAW,MAAM,SAAkB,KAAA,EAAU;AAE1D,KAAI,UAAU,MAAM;AAClB,UAAQ,MAAM;AACd,MAAI,UAAU,KAAM,UAAS,QAAQ,MAAM,CAAC;;CAE9C,MAAM,SAAS,kBAAkB,OAAO,MAAM;CAC9C,MAAM,WAAW,GAAG,GAAG;CAEvB,MAAM,UAAU,UAA0B;EACxC,MAAM,OAAO;GAAE,GAAG;GAAO,GAAG;GAAO;AACnC,WAAS,KAAK;EACd,MAAM,IAAI,kBAAkB,MAAM,MAAM;AACxC,MAAI,CAAC,EAAE,GAAI;AAEX,MADa,KAAK,UAAU,EAAE,MAAM,KAAK,KAAK,UAAU,SAAS,KAAK,CAC5D;AACV,UAAQ,EAAE,MAAM;AAChB,WAAS,EAAE,MAAM;;CAEnB,MAAM,cAAc,SAAwB,MAA2C;EACrF,MAAM,OAAO,KAAK,KAAK,EAAE,OAAO,MAAM;AACtC,SAAO,OAAO;GAAE,KAAK,KAAK;GAAI,KAAK,KAAK;GAAI,GAAI,GAAG,MAAM,EAAE,OAAO,OAAO,CAAoB;;CAG/F,MAAM,QAAQ,MAAM,MAAM,IAAI,OAAO,MAAM,QAAQ,YAAY,OAAO,MAAM,QAAQ,WAAW;EAAE,KAAK,MAAM;EAAK,KAAK,MAAM;EAAK,GAAG;AACpI,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,yCAAyC,UAAU,sCAAsC,kBAAkB;YAA9H,CACE,oBAAC,OAAD;GACE,WAAU;GACV,OAAO;IAAE,iBAAiB;IAAqI,gBAAgB;IAAa;aAE3L,QACC,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,OAAD;IAAK,WAAU;IAA0F,eAAA;cAAzG,CACE,oBAAC,QAAD;KAAM,WAAU;eACd,oBAAC,YAAD;MAAY,WAAU;MAAS,QAAQ;MAAO,CAAA;KACzC,CAAA,EACP,oBAAC,QAAD,EAAM,WAAU,oDAAqD,CAAA,CACjE;OACN,qBAAC,KAAD;IACE,MAAM,uCAAuC,MAAM,IAAI,QAAQ,MAAM,IAAI,UAAU,MAAM,IAAI,GAAG,MAAM;IACtG,QAAO;IACP,KAAI;IACJ,WAAU;IACV,cAAY,QAAQ,MAAM,IAAI,QAAQ,EAAE,CAAC,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;cALpE;KAOG,MAAM,IAAI,QAAQ,EAAE;KAAC;KAAG,MAAM,IAAI,QAAQ,EAAE;KAC7C,oBAAC,kBAAD;MAAkB,WAAU;MAAS,QAAQ;MAAK,eAAA;MAAc,CAAA;KAC9D;MACH,EAAA,CAAA,GAEH,oBAAC,KAAD;IAAG,WAAU;cAA8E;IAAsB,CAAA;GAE/G,CAAA,EACN,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,OAAD;KACM;KACJ,OAAO,MAAM;KACH;KACV,aAAY;KACZ,cAAY,GAAG,MAAM,MAAM;KAC3B,SAAS,oBAAC,YAAD,EAAY,QAAQ,KAAO,CAAA;KACpC,WAAW,MAAM,OAAO,EAAE,OAAO,EAAE,OAAO,OAAO,CAAC;KAClD,CAAA;IACF,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,OAAD;MACE,IAAI,GAAG,GAAG;MACV,MAAK;MACL,WAAU;MACV,OAAO,MAAM;MACH;MACV,cAAY,GAAG,MAAM,MAAM;MAC3B,gBAAe,CAAC,OAAO,MAAM,YAAY,KAAK,OAAO,OAAO,IAAK,KAAA;MACjE,oBAAkB,CAAC,OAAO,KAAK,WAAW,KAAA;MAC1C,aAAY;MACZ,UAAU,WAAW,MAAM;MAC3B,SAAS,oBAAC,QAAD;OAAM,WAAU;iBAAe;OAAU,CAAA;MAClD,CAAA,EACF,oBAAC,OAAD;MACE,IAAI,GAAG,GAAG;MACV,MAAK;MACL,WAAU;MACV,OAAO,MAAM;MACH;MACV,cAAY,GAAG,MAAM,MAAM;MAC3B,gBAAe,CAAC,OAAO,MAAM,aAAa,KAAK,OAAO,OAAO,IAAK,KAAA;MAClE,oBAAkB,CAAC,OAAO,KAAK,WAAW,KAAA;MAC1C,aAAY;MACZ,UAAU,WAAW,MAAM;MAC3B,SAAS,oBAAC,QAAD;OAAM,WAAU;iBAAe;OAAW,CAAA;MACnD,CAAA,CACE;;IACL,CAAC,OAAO,KACP,oBAAC,KAAD;KAAG,IAAI;KAAU,MAAK;KAAS,WAAU;eACtC,OAAO;KACN,CAAA,GACF;IACA;KACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ARRAY_CONTROLS } from "../engine/array.js";
|
|
2
|
+
import { CONTROLS } from "../engine/kit-field.js";
|
|
3
|
+
import { FileControl, GalleryControl, ImageControl, VideoControl } from "./media.js";
|
|
4
|
+
//#region src/kit/controls/media-register.ts
|
|
5
|
+
/** Lane C4: the media controls in the engine's dispatch tables (one line per type; merge with other lanes by line). */
|
|
6
|
+
CONTROLS.image = ImageControl;
|
|
7
|
+
CONTROLS.file = FileControl;
|
|
8
|
+
CONTROLS.video = VideoControl;
|
|
9
|
+
ARRAY_CONTROLS.gallery = GalleryControl;
|
|
10
|
+
//#endregion
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=media-register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-register.js","names":[],"sources":["../../src/kit/controls/media-register.ts"],"sourcesContent":["/** Lane C4: the media controls in the engine's dispatch tables (one line per type; merge with other lanes by line). */\nimport { CONTROLS } from \"../engine/kit-field\";\nimport { ARRAY_CONTROLS } from \"../engine/array\";\nimport { FileControl, GalleryControl, ImageControl, VideoControl } from \"./media\";\n\nCONTROLS.image = ImageControl;\nCONTROLS.file = FileControl;\nCONTROLS.video = VideoControl;\nARRAY_CONTROLS.gallery = GalleryControl;\n"],"mappings":";;;;;AAKA,SAAS,QAAQ;AACjB,SAAS,OAAO;AAChB,SAAS,QAAQ;AACjB,eAAe,UAAU"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The media services the image, gallery, file and video controls read (lane C4). Declared here as an augmentation of
|
|
3
|
+
* KitServices so context.tsx stays untouched by this lane; the host (the dock's KitPropsEditor, the /style-guide/kit
|
|
4
|
+
* sandbox) provides them through KitServicesProvider. Every one is optional, and a control whose service is absent says
|
|
5
|
+
* so in words instead of drawing a button that does nothing.
|
|
6
|
+
*
|
|
7
|
+
* Existing members the media controls also read: `MediaPicker` (the media library dialog), `onUploaded`, `toast`.
|
|
8
|
+
*/
|
|
9
|
+
import type { FieldPath } from "../schema/types";
|
|
10
|
+
export interface KitUploadOptions {
|
|
11
|
+
/** 0–1 across all files */
|
|
12
|
+
onProgress?: (fraction: number) => void;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
declare module "../context" {
|
|
16
|
+
interface KitServices {
|
|
17
|
+
/**
|
|
18
|
+
* Upload files into the project's media library and hand back the new assets. Rejects with an Error whose message
|
|
19
|
+
* is the reason, in words (the control shows it). Absent: the Upload button, drop and paste are not offered.
|
|
20
|
+
*/
|
|
21
|
+
uploadMedia?: (files: File[], opts: KitUploadOptions) => Promise<KitMediaAsset[]>;
|
|
22
|
+
/**
|
|
23
|
+
* True where an image placement stores its URL string only (the dock's top-level image props: PropsPanel codec
|
|
24
|
+
* "url"). Such an image never becomes an object, so alt text and focal point stay with the media asset.
|
|
25
|
+
*/
|
|
26
|
+
imageStoresUrl?: (path: FieldPath) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* A React hook (called on every render, so the provided function must stay the same): what the media library knows
|
|
29
|
+
* about a stored image or file (its name, pixel size, byte size, alt text). Absent or unknown → the caption shows
|
|
30
|
+
* only what the value and the loaded image tell.
|
|
31
|
+
*/
|
|
32
|
+
useMediaAsset?: (ref: {
|
|
33
|
+
id?: string;
|
|
34
|
+
url: string;
|
|
35
|
+
}) => KitMediaAsset | undefined;
|
|
36
|
+
/** The URL to draw a stored address with (a site-relative path on a code-built project needs the site origin). */
|
|
37
|
+
mediaSrc?: (url: string) => string;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MEDIA — image · gallery · file · video (V2 HEAD 9829bf1 kit/controls/media.tsx, DESIGN.md 8.15).
|
|
3
|
+
*
|
|
4
|
+
* Production parity: dashed drop well ("Add an image / Or drop or paste one here"), filled 16:9 preview with Replace and
|
|
5
|
+
* Remove pills, the caption "{file} · W × H · No alt text" and a ⋯ whose "Alt text and details" opens a popover (alt
|
|
6
|
+
* text, focal point, file name). The media library picker, the upload and the asset metadata are KitServices
|
|
7
|
+
* (media-services.ts): the kit never imports a feature, and a missing service is named in words, never faked.
|
|
8
|
+
*
|
|
9
|
+
* Kit deviations from V2, each because of what the backend stores (adapters/values.ts):
|
|
10
|
+
* - no "Crop for this placement" dropdown: `imageToProd` cannot store a crop preset (it becomes a pixel rect only with
|
|
11
|
+
* the asset's size, and never reads back as the preset), so the dock would refuse every write that carried one;
|
|
12
|
+
* - a picked asset's width / height / size are read for the caption, never written into the value (prod rebuilds the
|
|
13
|
+
* value from url, id, name, altText and focal; the rest would be refused);
|
|
14
|
+
* - where the host stores the URL string only (`imageStoresUrl`, the dock's top-level image props) the value stays a
|
|
15
|
+
* string, and alt text and focal point are the media library's (said in the details popover);
|
|
16
|
+
* - no built-in demo picker, no simulated upload, no stock poster frames;
|
|
17
|
+
* - the gallery sorts with the engine's `useDragReorder` (@dnd-kit is not on the kit allow-list);
|
|
18
|
+
* - a typed video URL is held as a draft until it is one prod stores (http(s) or a site path), so the dock never
|
|
19
|
+
* refuses a half-typed address.
|
|
20
|
+
*/
|
|
21
|
+
import * as React from "react";
|
|
22
|
+
import { type KitMediaAsset, type KitServices } from "../context";
|
|
23
|
+
import type { ControlProps } from "../types";
|
|
24
|
+
/** The image value the kit edits (V2 ImageValue, minus what prod cannot store: crop, caption, width, height, size). */
|
|
25
|
+
export interface ImageValue {
|
|
26
|
+
url: string;
|
|
27
|
+
alt?: string;
|
|
28
|
+
/** percent */
|
|
29
|
+
focal?: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
};
|
|
33
|
+
name?: string;
|
|
34
|
+
id?: string;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
export declare const fileNameFromUrl: (url: string) => string;
|
|
38
|
+
export declare const normImage: (v: unknown) => ImageValue | null;
|
|
39
|
+
/** What an asset becomes in a value: the keys prod keeps (url, id, name, alt), nothing measured. */
|
|
40
|
+
export declare const fromAsset: (a: KitMediaAsset) => ImageValue;
|
|
41
|
+
export declare const formatBytes: (n: number) => string;
|
|
42
|
+
/** An http(s) URL or a site path: what prod's video value takes (video-value.ts isVideoUrl). */
|
|
43
|
+
export declare const isVideoUrl: (s: string) => boolean;
|
|
44
|
+
/** Files the field takes, by `accept` (an `image/*`, `.pdf`, `*` list). */
|
|
45
|
+
export declare function acceptsFile(accept: string, file: Pick<File, "type" | "name">): boolean;
|
|
46
|
+
export declare function MediaPicker(p: React.ComponentProps<NonNullable<KitServices["MediaPicker"]>>): import("react/jsx-runtime").JSX.Element | null;
|
|
47
|
+
/**
|
|
48
|
+
* Upload through the host's media library: progress while it runs, the assets handed to `onDone`, and a named reason
|
|
49
|
+
* when it fails or a file is the wrong kind. `run` is undefined when the host has no upload service.
|
|
50
|
+
*/
|
|
51
|
+
export declare function useUpload(accept: string, kind: string, onDone: (a: KitMediaAsset[]) => void): {
|
|
52
|
+
progress: number | null;
|
|
53
|
+
error: string | null;
|
|
54
|
+
setError: React.Dispatch<React.SetStateAction<string | null>>;
|
|
55
|
+
run: ((files: File[]) => void) | undefined;
|
|
56
|
+
};
|
|
57
|
+
export declare function ImageControl({ field, value, onChange: write, readOnly, id, path }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
/** An array of images: a sortable grid of tiles with a dashed "Add images" tile last (hidden at `max`). */
|
|
59
|
+
export declare function GalleryControl({ value, onChange, readOnly, field, id }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
export declare function FileControl({ value, onChange, readOnly, id }: ControlProps): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
export declare const videoProvider: (url: string) => "Link" | "" | "YouTube" | "Vimeo" | "Loom" | "MP4";
|
|
62
|
+
export declare const youTubeId: (url: string) => string | undefined;
|
|
63
|
+
export declare function VideoPreview({ url, poster, title }: {
|
|
64
|
+
url: string;
|
|
65
|
+
poster?: string;
|
|
66
|
+
title: string;
|
|
67
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
68
|
+
/**
|
|
69
|
+
* A URL input with a live preview. The value keeps its stored shape: a URL string stays a string, a `{ url, poster… }`
|
|
70
|
+
* object keeps its other keys. What is typed is a draft until it is an address prod stores (http(s) or a site path);
|
|
71
|
+
* until then the field keeps the saved value and says why under the input.
|
|
72
|
+
*/
|
|
73
|
+
export declare function VideoControl({ field, value, onChange, readOnly, id, onBlur }: ControlProps): import("react/jsx-runtime").JSX.Element;
|