@greypan/web-ui 11.2.0 → 12.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/README.CN.md +79 -68
- package/README.md +81 -72
- package/dist/_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js +8 -0
- package/dist/assets/menu-portal.js +3 -4
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/modal-surface.js +3 -4
- package/dist/assets/modal-surface.js.map +1 -1
- package/dist/assets/overlay-motion.js +3 -4
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/assets/scrollbar.js +5 -0
- package/dist/assets/scrollbar.js.map +1 -0
- package/dist/assets/selection-control.js +3 -4
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/assets/toast-containers.js +3 -4
- package/dist/assets/toast-containers.js.map +1 -1
- package/dist/classes/glass.js +3 -4
- package/dist/classes/glass.js.map +1 -1
- package/dist/classes/glow.js +3 -4
- package/dist/classes/glow.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +485 -483
- package/dist/components/autocomplete/index.d.ts.map +1 -0
- package/dist/components/autocomplete/index.js +475 -267
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +3 -4
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/index.d.ts +26 -24
- package/dist/components/avatar/index.d.ts.map +1 -0
- package/dist/components/avatar/index.js +72 -52
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/avatar/style.js +3 -4
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/index.d.ts +30 -27
- package/dist/components/back-top/index.d.ts.map +1 -0
- package/dist/components/back-top/index.js +96 -62
- package/dist/components/back-top/index.js.map +1 -1
- package/dist/components/back-top/style.js +3 -4
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/index.d.ts +32 -26
- package/dist/components/badge/index.d.ts.map +1 -0
- package/dist/components/badge/index.js +116 -74
- package/dist/components/badge/index.js.map +1 -1
- package/dist/components/badge/style.js +3 -4
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/index.d.ts +392 -390
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/index.js +108 -74
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +3 -4
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/index.d.ts +14 -13
- package/dist/components/button-group/index.d.ts.map +1 -0
- package/dist/components/button-group/index.js +43 -33
- package/dist/components/button-group/index.js.map +1 -1
- package/dist/components/button-group/style.js +3 -4
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +399 -397
- package/dist/components/checkbox/index.d.ts.map +1 -0
- package/dist/components/checkbox/index.js +103 -74
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +3 -4
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +397 -396
- package/dist/components/checkbox-group/index.d.ts.map +1 -0
- package/dist/components/checkbox-group/index.js +92 -70
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/checkbox-group/style.js +3 -4
- package/dist/components/checkbox-group/style.js.map +1 -1
- package/dist/components/collapse/index.d.ts +72 -71
- package/dist/components/collapse/index.d.ts.map +1 -0
- package/dist/components/collapse/index.js +225 -130
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +3 -4
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +307 -310
- package/dist/components/context-menu/index.d.ts.map +1 -0
- package/dist/components/context-menu/index.js +685 -270
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/context-menu/scrim.js +3 -4
- package/dist/components/context-menu/scrim.js.map +1 -1
- package/dist/components/context-menu/style.js +3 -4
- package/dist/components/context-menu/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +87 -78
- package/dist/components/dialog/index.d.ts.map +1 -0
- package/dist/components/dialog/index.js +183 -88
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +3 -4
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +159 -150
- package/dist/components/drawer/index.d.ts.map +1 -0
- package/dist/components/drawer/index.js +503 -242
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +3 -4
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +125 -124
- package/dist/components/dropdown/index.d.ts.map +1 -0
- package/dist/components/dropdown/index.js +556 -328
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown/style.js +3 -4
- package/dist/components/dropdown/style.js.map +1 -1
- package/dist/components/dropdown-divider/index.d.ts +7 -6
- package/dist/components/dropdown-divider/index.d.ts.map +1 -0
- package/dist/components/dropdown-divider/index.js +10 -11
- package/dist/components/dropdown-divider/index.js.map +1 -1
- package/dist/components/dropdown-divider/style.js +3 -4
- package/dist/components/dropdown-divider/style.js.map +1 -1
- package/dist/components/dropdown-header/index.d.ts +7 -6
- package/dist/components/dropdown-header/index.d.ts.map +1 -0
- package/dist/components/dropdown-header/index.js +10 -11
- package/dist/components/dropdown-header/index.js.map +1 -1
- package/dist/components/dropdown-header/style.js +3 -4
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/index.d.ts +13 -11
- package/dist/components/dropdown-item/index.d.ts.map +1 -0
- package/dist/components/dropdown-item/index.js +32 -25
- package/dist/components/dropdown-item/index.js.map +1 -1
- package/dist/components/dropdown-item/style.js +3 -4
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/editable-text/index.d.ts +506 -505
- package/dist/components/editable-text/index.d.ts.map +1 -0
- package/dist/components/editable-text/index.js +281 -127
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/editable-text/style.js +3 -4
- package/dist/components/editable-text/style.js.map +1 -1
- package/dist/components/empty/index.d.ts +17 -15
- package/dist/components/empty/index.d.ts.map +1 -0
- package/dist/components/empty/index.js +66 -37
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/empty/style.js +3 -4
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/icon/index.d.ts +12 -11
- package/dist/components/icon/index.d.ts.map +1 -0
- package/dist/components/icon/index.js +34 -27
- package/dist/components/icon/index.js.map +1 -1
- package/dist/components/icon/style.js +3 -4
- package/dist/components/icon/style.js.map +1 -1
- package/dist/components/image-preview/index.d.ts +58 -44
- package/dist/components/image-preview/index.d.ts.map +1 -0
- package/dist/components/image-preview/index.js +536 -265
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/image-preview/style.js +3 -4
- package/dist/components/image-preview/style.js.map +1 -1
- package/dist/components/index.d.ts +46 -43
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +41 -41
- package/dist/components/input/index.d.ts +418 -413
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +148 -84
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +3 -4
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +453 -447
- package/dist/components/input-number/index.d.ts.map +1 -0
- package/dist/components/input-number/index.js +484 -292
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +3 -4
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +110 -87
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +238 -144
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +3 -4
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +93 -92
- package/dist/components/middle-ellipsis/index.d.ts.map +1 -0
- package/dist/components/middle-ellipsis/index.js +261 -107
- package/dist/components/middle-ellipsis/index.js.map +1 -1
- package/dist/components/middle-ellipsis/style.js +3 -4
- package/dist/components/middle-ellipsis/style.js.map +1 -1
- package/dist/components/middle-ellipsis/truncate.js +60 -30
- package/dist/components/middle-ellipsis/truncate.js.map +1 -1
- package/dist/components/option/index.d.ts +20 -18
- package/dist/components/option/index.d.ts.map +1 -0
- package/dist/components/option/index.js +53 -40
- package/dist/components/option/index.js.map +1 -1
- package/dist/components/option/style.js +3 -4
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +69 -68
- package/dist/components/popover/index.d.ts.map +1 -0
- package/dist/components/popover/index.js +221 -104
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +3 -4
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +396 -395
- package/dist/components/radio/index.d.ts.map +1 -0
- package/dist/components/radio/index.js +91 -62
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/interaction.js +10 -11
- package/dist/components/radio/interaction.js.map +1 -1
- package/dist/components/radio/style.js +3 -4
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +417 -416
- package/dist/components/radio-group/index.d.ts.map +1 -0
- package/dist/components/radio-group/index.js +307 -207
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/radio-group/style.js +3 -4
- package/dist/components/radio-group/style.js.map +1 -1
- package/dist/components/segmented/index.d.ts +408 -402
- package/dist/components/segmented/index.d.ts.map +1 -0
- package/dist/components/segmented/index.js +267 -158
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +3 -4
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.d.ts +18 -17
- package/dist/components/segmented-trigger/index.d.ts.map +1 -0
- package/dist/components/segmented-trigger/index.js +45 -36
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +3 -4
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +450 -448
- package/dist/components/select/index.d.ts.map +1 -0
- package/dist/components/select/index.js +342 -188
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +3 -4
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +428 -427
- package/dist/components/slider/index.d.ts.map +1 -0
- package/dist/components/slider/index.js +308 -216
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +3 -4
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/index.d.ts +39 -38
- package/dist/components/spinner/index.d.ts.map +1 -0
- package/dist/components/spinner/index.js +118 -65
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/spinner/style.js +3 -4
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.d.ts +40 -39
- package/dist/components/svg-draw-lines/index.d.ts.map +1 -0
- package/dist/components/svg-draw-lines/index.js +189 -106
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/svg-draw-lines/style.js +3 -4
- package/dist/components/svg-draw-lines/style.js.map +1 -1
- package/dist/components/switch/index.d.ts +411 -409
- package/dist/components/switch/index.d.ts.map +1 -0
- package/dist/components/switch/index.js +193 -106
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +3 -4
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +430 -425
- package/dist/components/textarea/index.d.ts.map +1 -0
- package/dist/components/textarea/index.js +187 -100
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +3 -4
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.d.ts +45 -44
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/index.js +268 -161
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +3 -4
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/index.d.ts +4 -3
- package/dist/components/toast/index.js +3 -3
- package/dist/components/toast/manager.d.ts +9 -8
- package/dist/components/toast/manager.d.ts.map +1 -0
- package/dist/components/toast/manager.js +215 -119
- package/dist/components/toast/manager.js.map +1 -1
- package/dist/components/toast/style.js +3 -4
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/toast/toast.d.ts +75 -71
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +203 -96
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/types.d.ts +10 -9
- package/dist/components/toast/types.d.ts.map +1 -0
- package/dist/components/tooltip/index.d.ts +72 -62
- package/dist/components/tooltip/index.d.ts.map +1 -0
- package/dist/components/tooltip/index.js +251 -93
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +3 -4
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/icons/generated/akar-icons-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-check.js +3 -4
- package/dist/icons/generated/akar-icons-check.js.map +1 -1
- package/dist/icons/generated/akar-icons-circle-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-circle-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-circle-check.js +3 -4
- package/dist/icons/generated/akar-icons-circle-check.js.map +1 -1
- package/dist/icons/generated/andrsrxn-inbox.d.ts +5 -4
- package/dist/icons/generated/andrsrxn-inbox.d.ts.map +1 -0
- package/dist/icons/generated/andrsrxn-inbox.js +3 -4
- package/dist/icons/generated/andrsrxn-inbox.js.map +1 -1
- package/dist/icons/generated/bi-check-lg.d.ts +5 -4
- package/dist/icons/generated/bi-check-lg.d.ts.map +1 -0
- package/dist/icons/generated/bi-check-lg.js +3 -4
- package/dist/icons/generated/bi-check-lg.js.map +1 -1
- package/dist/icons/generated/bi-check.d.ts +5 -4
- package/dist/icons/generated/bi-check.d.ts.map +1 -0
- package/dist/icons/generated/bi-check.js +3 -4
- package/dist/icons/generated/bi-check.js.map +1 -1
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +5 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts.map +1 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.js +3 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-check-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-check-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-check-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-check-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-x-mark-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.js.map +1 -1
- package/dist/icons/generated/jam-close-circle-f.d.ts +7 -6
- package/dist/icons/generated/jam-close-circle-f.d.ts.map +1 -0
- package/dist/icons/generated/jam-close-circle-f.js +3 -4
- package/dist/icons/generated/jam-close-circle-f.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-down-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-up-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-bell.d.ts +5 -4
- package/dist/icons/generated/lucide-bell.d.ts.map +1 -0
- package/dist/icons/generated/lucide-bell.js +3 -4
- package/dist/icons/generated/lucide-bell.js.map +1 -1
- package/dist/icons/generated/lucide-check.d.ts +5 -4
- package/dist/icons/generated/lucide-check.d.ts.map +1 -0
- package/dist/icons/generated/lucide-check.js +3 -4
- package/dist/icons/generated/lucide-check.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-down.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-down.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-down.js +3 -4
- package/dist/icons/generated/lucide-chevron-down.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-left.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-left.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-left.js +3 -4
- package/dist/icons/generated/lucide-chevron-left.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-right.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-right.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-right.js +3 -4
- package/dist/icons/generated/lucide-chevron-right.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-up.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-up.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-up.js +3 -4
- package/dist/icons/generated/lucide-chevron-up.js.map +1 -1
- package/dist/icons/generated/lucide-circle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-circle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-circle-alert.js +3 -4
- package/dist/icons/generated/lucide-circle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-clapperboard.d.ts +5 -4
- package/dist/icons/generated/lucide-clapperboard.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clapperboard.js +3 -4
- package/dist/icons/generated/lucide-clapperboard.js.map +1 -1
- package/dist/icons/generated/lucide-clipboard-paste.d.ts +5 -4
- package/dist/icons/generated/lucide-clipboard-paste.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clipboard-paste.js +3 -4
- package/dist/icons/generated/lucide-clipboard-paste.js.map +1 -1
- package/dist/icons/generated/lucide-code.d.ts +5 -4
- package/dist/icons/generated/lucide-code.d.ts.map +1 -0
- package/dist/icons/generated/lucide-code.js +3 -4
- package/dist/icons/generated/lucide-code.js.map +1 -1
- package/dist/icons/generated/lucide-copy.d.ts +5 -4
- package/dist/icons/generated/lucide-copy.d.ts.map +1 -0
- package/dist/icons/generated/lucide-copy.js +3 -4
- package/dist/icons/generated/lucide-copy.js.map +1 -1
- package/dist/icons/generated/lucide-download.d.ts +5 -4
- package/dist/icons/generated/lucide-download.d.ts.map +1 -0
- package/dist/icons/generated/lucide-download.js +3 -4
- package/dist/icons/generated/lucide-download.js.map +1 -1
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts +5 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts.map +1 -0
- package/dist/icons/generated/lucide-ellipsis-vertical.js +3 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.js.map +1 -1
- package/dist/icons/generated/lucide-external-link.d.ts +5 -4
- package/dist/icons/generated/lucide-external-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-external-link.js +3 -4
- package/dist/icons/generated/lucide-external-link.js.map +1 -1
- package/dist/icons/generated/lucide-eye.d.ts +5 -4
- package/dist/icons/generated/lucide-eye.d.ts.map +1 -0
- package/dist/icons/generated/lucide-eye.js +3 -4
- package/dist/icons/generated/lucide-eye.js.map +1 -1
- package/dist/icons/generated/lucide-file-text.d.ts +5 -4
- package/dist/icons/generated/lucide-file-text.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file-text.js +3 -4
- package/dist/icons/generated/lucide-file-text.js.map +1 -1
- package/dist/icons/generated/lucide-file.d.ts +5 -4
- package/dist/icons/generated/lucide-file.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file.js +3 -4
- package/dist/icons/generated/lucide-file.js.map +1 -1
- package/dist/icons/generated/lucide-film.d.ts +5 -4
- package/dist/icons/generated/lucide-film.d.ts.map +1 -0
- package/dist/icons/generated/lucide-film.js +3 -4
- package/dist/icons/generated/lucide-film.js.map +1 -1
- package/dist/icons/generated/lucide-folder-open.d.ts +5 -4
- package/dist/icons/generated/lucide-folder-open.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder-open.js +3 -4
- package/dist/icons/generated/lucide-folder-open.js.map +1 -1
- package/dist/icons/generated/lucide-folder.d.ts +5 -4
- package/dist/icons/generated/lucide-folder.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder.js +3 -4
- package/dist/icons/generated/lucide-folder.js.map +1 -1
- package/dist/icons/generated/lucide-globe.d.ts +5 -4
- package/dist/icons/generated/lucide-globe.d.ts.map +1 -0
- package/dist/icons/generated/lucide-globe.js +3 -4
- package/dist/icons/generated/lucide-globe.js.map +1 -1
- package/dist/icons/generated/lucide-headphones.d.ts +5 -4
- package/dist/icons/generated/lucide-headphones.d.ts.map +1 -0
- package/dist/icons/generated/lucide-headphones.js +3 -4
- package/dist/icons/generated/lucide-headphones.js.map +1 -1
- package/dist/icons/generated/lucide-heart.d.ts +5 -4
- package/dist/icons/generated/lucide-heart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-heart.js +3 -4
- package/dist/icons/generated/lucide-heart.js.map +1 -1
- package/dist/icons/generated/lucide-image.d.ts +5 -4
- package/dist/icons/generated/lucide-image.d.ts.map +1 -0
- package/dist/icons/generated/lucide-image.js +3 -4
- package/dist/icons/generated/lucide-image.js.map +1 -1
- package/dist/icons/generated/lucide-inbox.d.ts +5 -4
- package/dist/icons/generated/lucide-inbox.d.ts.map +1 -0
- package/dist/icons/generated/lucide-inbox.js +3 -4
- package/dist/icons/generated/lucide-inbox.js.map +1 -1
- package/dist/icons/generated/lucide-info.d.ts +5 -4
- package/dist/icons/generated/lucide-info.d.ts.map +1 -0
- package/dist/icons/generated/lucide-info.js +3 -4
- package/dist/icons/generated/lucide-info.js.map +1 -1
- package/dist/icons/generated/lucide-layout-grid.d.ts +5 -4
- package/dist/icons/generated/lucide-layout-grid.d.ts.map +1 -0
- package/dist/icons/generated/lucide-layout-grid.js +3 -4
- package/dist/icons/generated/lucide-layout-grid.js.map +1 -1
- package/dist/icons/generated/lucide-link.d.ts +5 -4
- package/dist/icons/generated/lucide-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-link.js +3 -4
- package/dist/icons/generated/lucide-link.js.map +1 -1
- package/dist/icons/generated/lucide-list-filter.d.ts +5 -4
- package/dist/icons/generated/lucide-list-filter.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-filter.js +3 -4
- package/dist/icons/generated/lucide-list-filter.js.map +1 -1
- package/dist/icons/generated/lucide-list-restart.d.ts +5 -4
- package/dist/icons/generated/lucide-list-restart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-restart.js +3 -4
- package/dist/icons/generated/lucide-list-restart.js.map +1 -1
- package/dist/icons/generated/lucide-loader-circle.d.ts +5 -4
- package/dist/icons/generated/lucide-loader-circle.d.ts.map +1 -0
- package/dist/icons/generated/lucide-loader-circle.js +3 -4
- package/dist/icons/generated/lucide-loader-circle.js.map +1 -1
- package/dist/icons/generated/lucide-mail.d.ts +5 -4
- package/dist/icons/generated/lucide-mail.d.ts.map +1 -0
- package/dist/icons/generated/lucide-mail.js +3 -4
- package/dist/icons/generated/lucide-mail.js.map +1 -1
- package/dist/icons/generated/lucide-minus.d.ts +5 -4
- package/dist/icons/generated/lucide-minus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-minus.js +3 -4
- package/dist/icons/generated/lucide-minus.js.map +1 -1
- package/dist/icons/generated/lucide-music.d.ts +5 -4
- package/dist/icons/generated/lucide-music.d.ts.map +1 -0
- package/dist/icons/generated/lucide-music.js +3 -4
- package/dist/icons/generated/lucide-music.js.map +1 -1
- package/dist/icons/generated/lucide-package.d.ts +5 -4
- package/dist/icons/generated/lucide-package.d.ts.map +1 -0
- package/dist/icons/generated/lucide-package.js +3 -4
- package/dist/icons/generated/lucide-package.js.map +1 -1
- package/dist/icons/generated/lucide-pen-line.d.ts +5 -4
- package/dist/icons/generated/lucide-pen-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pen-line.js +3 -4
- package/dist/icons/generated/lucide-pen-line.js.map +1 -1
- package/dist/icons/generated/lucide-pencil.d.ts +5 -4
- package/dist/icons/generated/lucide-pencil.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pencil.js +3 -4
- package/dist/icons/generated/lucide-pencil.js.map +1 -1
- package/dist/icons/generated/lucide-play.d.ts +5 -4
- package/dist/icons/generated/lucide-play.d.ts.map +1 -0
- package/dist/icons/generated/lucide-play.js +3 -4
- package/dist/icons/generated/lucide-play.js.map +1 -1
- package/dist/icons/generated/lucide-plus.d.ts +5 -4
- package/dist/icons/generated/lucide-plus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-plus.js +3 -4
- package/dist/icons/generated/lucide-plus.js.map +1 -1
- package/dist/icons/generated/lucide-printer.d.ts +5 -4
- package/dist/icons/generated/lucide-printer.d.ts.map +1 -0
- package/dist/icons/generated/lucide-printer.js +3 -4
- package/dist/icons/generated/lucide-printer.js.map +1 -1
- package/dist/icons/generated/lucide-redo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-redo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-redo-2.js +3 -4
- package/dist/icons/generated/lucide-redo-2.js.map +1 -1
- package/dist/icons/generated/lucide-refresh-cw.d.ts +5 -4
- package/dist/icons/generated/lucide-refresh-cw.d.ts.map +1 -0
- package/dist/icons/generated/lucide-refresh-cw.js +3 -4
- package/dist/icons/generated/lucide-refresh-cw.js.map +1 -1
- package/dist/icons/generated/lucide-scissors.d.ts +5 -4
- package/dist/icons/generated/lucide-scissors.d.ts.map +1 -0
- package/dist/icons/generated/lucide-scissors.js +3 -4
- package/dist/icons/generated/lucide-scissors.js.map +1 -1
- package/dist/icons/generated/lucide-search.d.ts +5 -4
- package/dist/icons/generated/lucide-search.d.ts.map +1 -0
- package/dist/icons/generated/lucide-search.js +3 -4
- package/dist/icons/generated/lucide-search.js.map +1 -1
- package/dist/icons/generated/lucide-settings.d.ts +5 -4
- package/dist/icons/generated/lucide-settings.d.ts.map +1 -0
- package/dist/icons/generated/lucide-settings.js +3 -4
- package/dist/icons/generated/lucide-settings.js.map +1 -1
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts +5 -4
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts.map +1 -0
- package/dist/icons/generated/lucide-sliders-horizontal.js +3 -4
- package/dist/icons/generated/lucide-sliders-horizontal.js.map +1 -1
- package/dist/icons/generated/lucide-star.d.ts +5 -4
- package/dist/icons/generated/lucide-star.d.ts.map +1 -0
- package/dist/icons/generated/lucide-star.js +3 -4
- package/dist/icons/generated/lucide-star.js.map +1 -1
- package/dist/icons/generated/lucide-tag.d.ts +5 -4
- package/dist/icons/generated/lucide-tag.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tag.js +3 -4
- package/dist/icons/generated/lucide-tag.js.map +1 -1
- package/dist/icons/generated/lucide-tags.d.ts +5 -4
- package/dist/icons/generated/lucide-tags.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tags.js +3 -4
- package/dist/icons/generated/lucide-tags.js.map +1 -1
- package/dist/icons/generated/lucide-trash-2.d.ts +5 -4
- package/dist/icons/generated/lucide-trash-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-trash-2.js +3 -4
- package/dist/icons/generated/lucide-trash-2.js.map +1 -1
- package/dist/icons/generated/lucide-triangle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-triangle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-triangle-alert.js +3 -4
- package/dist/icons/generated/lucide-triangle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-undo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-undo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-undo-2.js +3 -4
- package/dist/icons/generated/lucide-undo-2.js.map +1 -1
- package/dist/icons/generated/lucide-upload.d.ts +5 -4
- package/dist/icons/generated/lucide-upload.d.ts.map +1 -0
- package/dist/icons/generated/lucide-upload.js +3 -4
- package/dist/icons/generated/lucide-upload.js.map +1 -1
- package/dist/icons/generated/lucide-user.d.ts +5 -4
- package/dist/icons/generated/lucide-user.d.ts.map +1 -0
- package/dist/icons/generated/lucide-user.js +3 -4
- package/dist/icons/generated/lucide-user.js.map +1 -1
- package/dist/icons/generated/lucide-wrench.d.ts +5 -4
- package/dist/icons/generated/lucide-wrench.d.ts.map +1 -0
- package/dist/icons/generated/lucide-wrench.js +3 -4
- package/dist/icons/generated/lucide-wrench.js.map +1 -1
- package/dist/icons/generated/lucide-x.d.ts +5 -4
- package/dist/icons/generated/lucide-x.d.ts.map +1 -0
- package/dist/icons/generated/lucide-x.js +3 -4
- package/dist/icons/generated/lucide-x.js.map +1 -1
- package/dist/icons/generated/mdi-tag-search-outline.d.ts +5 -4
- package/dist/icons/generated/mdi-tag-search-outline.d.ts.map +1 -0
- package/dist/icons/generated/mdi-tag-search-outline.js +3 -4
- package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -1
- package/dist/icons/generated/ooui-close.d.ts +5 -4
- package/dist/icons/generated/ooui-close.d.ts.map +1 -0
- package/dist/icons/generated/ooui-close.js +3 -4
- package/dist/icons/generated/ooui-close.js.map +1 -1
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts +5 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-panel-left-minimized.js +3 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.js.map +1 -1
- package/dist/icons/generated/radix-icons-reset.d.ts +5 -4
- package/dist/icons/generated/radix-icons-reset.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-reset.js +3 -4
- package/dist/icons/generated/radix-icons-reset.js.map +1 -1
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts +5 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts.map +1 -0
- package/dist/icons/generated/tabler-sort-ascending-letters.js +3 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.js.map +1 -1
- package/dist/icons/index.d.ts +75 -74
- package/dist/icons/index.js +75 -75
- package/dist/shared/element-height/index.js +51 -25
- package/dist/shared/element-height/index.js.map +1 -1
- package/dist/shared/element-width/index.js +39 -24
- package/dist/shared/element-width/index.js.map +1 -1
- package/dist/shared/events/user-change.js +14 -8
- package/dist/shared/events/user-change.js.map +1 -1
- package/dist/shared/focus/pointer-focus.js +56 -30
- package/dist/shared/focus/pointer-focus.js.map +1 -1
- package/dist/shared/focus/tabbable.js +96 -0
- package/dist/shared/focus/tabbable.js.map +1 -0
- package/dist/shared/form-association/field-id.js +13 -6
- package/dist/shared/form-association/field-id.js.map +1 -1
- package/dist/shared/form-association/index.js +75 -42
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +239 -99
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/gesture/physics.js +49 -16
- package/dist/shared/gesture/physics.js.map +1 -1
- package/dist/shared/gesture/pinch-gesture.js +111 -60
- package/dist/shared/gesture/pinch-gesture.js.map +1 -1
- package/dist/shared/group-management/index.js +181 -84
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/label-emptiness/index.js +45 -26
- package/dist/shared/label-emptiness/index.js.map +1 -1
- package/dist/shared/locale/builtin-labels.js +38 -0
- package/dist/shared/locale/builtin-labels.js.map +1 -0
- package/dist/shared/menu-behavior/index.js +113 -60
- package/dist/shared/menu-behavior/index.js.map +1 -1
- package/dist/shared/menu-portal/menu-portal.js +47 -26
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/menu-portal/menu-tree.js +132 -75
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/normalize/index.js +16 -7
- package/dist/shared/normalize/index.js.map +1 -1
- package/dist/shared/open-state/index.js +7 -8
- package/dist/shared/open-state/index.js.map +1 -1
- package/dist/shared/option-portal/combobox-shell.js +121 -56
- package/dist/shared/option-portal/combobox-shell.js.map +1 -1
- package/dist/shared/option-portal/index.js +65 -44
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js +75 -40
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js +116 -52
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/nested-drawer-layers.js +76 -46
- package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
- package/dist/shared/overlay/open-overlay.js +240 -136
- package/dist/shared/overlay/open-overlay.js.map +1 -1
- package/dist/shared/overlay/overlay-root.js +33 -24
- package/dist/shared/overlay/overlay-root.js.map +1 -1
- package/dist/shared/overlay/overlay.js +109 -66
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/placement-props.js +9 -4
- package/dist/shared/overlay/placement-props.js.map +1 -1
- package/dist/shared/overlay/portal.d.ts +2 -0
- package/dist/shared/overlay/portal.d.ts.map +1 -0
- package/dist/shared/overlay/portal.js +202 -117
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/positioning-generation.js +9 -10
- package/dist/shared/overlay/positioning-generation.js.map +1 -1
- package/dist/shared/overlay/presence.js +43 -21
- package/dist/shared/overlay/presence.js.map +1 -1
- package/dist/shared/overlay/theme-overlay-scope.js +22 -19
- package/dist/shared/overlay/theme-overlay-scope.js.map +1 -1
- package/dist/shared/scroll-lock/scroll-lock.js +49 -15
- package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
- package/dist/shared/theme/duration.js +13 -6
- package/dist/shared/theme/duration.js.map +1 -1
- package/dist/shared/theme/reduced-motion.js +14 -9
- package/dist/shared/theme/reduced-motion.js.map +1 -1
- package/dist/shared/theme/root-sync.js +85 -32
- package/dist/shared/theme/root-sync.js.map +1 -1
- package/dist/shared/visible-area/index.js +81 -37
- package/dist/shared/visible-area/index.js.map +1 -1
- package/dist/types/iconify.d.ts +1 -1
- package/dist/types/iconify.js +0 -0
- package/dist/types/react.d.ts +8 -10
- package/dist/types/react.d.ts.map +1 -0
- package/dist/types/react.js +0 -0
- package/dist/types/utils.d.ts +8 -13
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +0 -0
- package/dist/types/vue.d.ts +9 -13
- package/dist/types/vue.d.ts.map +1 -0
- package/dist/types/vue.js +0 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +30 -4
- package/dist/vite/index.js.map +1 -1
- package/package.json +10 -23
- package/dist/_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js +0 -9
- package/dist/components/middle-ellipsis/truncate.d.ts +0 -62
- package/dist/components/radio/interaction.d.ts +0 -4
- package/dist/scrollbars/index.d.ts +0 -33
- package/dist/scrollbars/index.js +0 -18
- package/dist/scrollbars/index.js.map +0 -1
- package/dist/scrollbars/internal.js +0 -6
- package/dist/scrollbars/internal.js.map +0 -1
- package/dist/scrollbars/style.css +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/editable-text/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { createFieldId } from '@/shared/form-association/field-id'\n\nimport style from './style.css?inline'\n\n/** 空值且无 placeholder 时保留可点击行盒。 */\nconst BLANK_GLYPH = '\\u200B'\n\n/** 行/字符落点二分的容差(px),吸收次像素与舍入差异。 */\nconst CARET_TOLERANCE = 1\n\n/**\n * 取文本层承载文案的 Text 节点。\n *\n * 绑定表达式位于元素首个位置时,Lit 会在它前面留一个注释标记节点,因此不能用\n * `firstChild`:那会拿到没有布局的注释,Range 量不到任何矩形。\n */\nfunction textNodeOf(layer: HTMLElement): Text | null {\n for (const child of layer.childNodes) {\n if (child instanceof Text) return child\n }\n return null\n}\n\n/**\n * 把视口坐标映射为文本层的字符偏移。\n *\n * `document.caretPositionFromPoint` 不进入 shadow DOM(对 shadow 内容返回 shadow host\n * 之外的节点),因此在文本层上用 Range 空矩形二分:先按 y 选行,再在行内按 x 选字符。\n * 文本层与编辑层同盒同排版,偏移与 textarea 的 selectionStart 一一对应。\n */\nfunction caretOffsetFromPoint(textLayer: HTMLElement, x: number, y: number): number {\n const node = textNodeOf(textLayer)\n if (!node) return 0\n const length = node.data.length\n const range = document.createRange()\n const rectAt = (offset: number): DOMRect => {\n range.setStart(node, offset)\n range.setEnd(node, offset)\n return range.getBoundingClientRect()\n }\n\n // 同一行的盒可能被拆成多个 client rect;按 top 去重得到行列表,取与 y 最近的一行,\n // 距离相等时取更靠下的一行(与浏览器在行间的落点行为一致)。\n const lines: DOMRect[] = []\n for (const rect of textLayer.getClientRects()) {\n if (!lines.some(line => Math.abs(line.top - rect.top) <= CARET_TOLERANCE)) lines.push(rect)\n }\n if (lines.length === 0) return length\n let line = lines[0]\n let nearest = Infinity\n for (const candidate of lines) {\n const distance = Math.abs((candidate.top + candidate.bottom) / 2 - y)\n if (distance <= nearest) {\n nearest = distance\n line = candidate\n }\n }\n\n // 行首:caret top 首次落入本行的最小偏移\n let lo = 0\n let hi = length\n while (lo < hi) {\n const mid = (lo + hi) >> 1\n if (rectAt(mid).top >= line.top - CARET_TOLERANCE) hi = mid\n else lo = mid + 1\n }\n const lineStart = lo\n // 行尾:caret top 仍落在本行的最大偏移\n lo = lineStart\n hi = length\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (rectAt(mid).top <= line.top + CARET_TOLERANCE) lo = mid\n else hi = mid - 1\n }\n const lineEnd = Math.max(lo, lineStart)\n // 行内:caret left 不超过 x 的最大偏移\n lo = lineStart\n hi = lineEnd\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (rectAt(mid).left <= x + CARET_TOLERANCE) lo = mid\n else hi = mid - 1\n }\n return lo\n}\n\n@customElement('web-ui-editable-text')\nexport class WebUiEditableText extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: String, reflect: true }) placeholder = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) readonly = false\n\n /**\n * 卸载时按提交语义结束编辑,默认 false。\n *\n * 跨引擎实测(Chromium 与 WebKit 各一轮)结论**不一致**,这是本属性的主要价值来源:\n *\n * - Chromium:移除正在编辑的组件会向编辑层派发 `blur`,默认行为下 `change` 已照常派发\n * 一次,草稿不丢。blur 与 change 同步排在 `disconnectedCallback` 之后(后者在\n * disconnected 步骤内跑完),卸载因此没拿到一条「排在该消费方状态更新之前」的提交来源。\n * - WebKit(Safari / iOS):移除**不派发 blur**,默认路径什么都不提交,草稿随组件一起丢弃。\n * 这里 blur 兜底不存在,只有显式开启本属性才能保住草稿。\n * - Gecko(Firefox)**未验证**:实测所用机器上没有任何 Firefox 能启动,这里不做断言。把它当作\n * 未知,而不是默认与上面两者之一相同。\n *\n * 所以在 Safari 上这不是可选优化而是必需的:默认值 `false` 对 Safari 用户等于没有兜底,\n * 消费方若依赖「行被回收时草稿不丢」,在 Safari 上必须显式开启本属性。\n *\n * 开启后由 `disconnectedCallback` 复用 `_commitEditing`,与 `Enter`/`blur` 是同一份实现,\n * 卸载不是第三条独立的提交语义。副作用与 `blur` 提交一致:草稿成为新值、退出编辑、\n * 派发一次 `change`(冒泡且组合)。两处与 `blur` 刻意不同:\n *\n * 1. 提交判据——`Enter` 与 `blur` 由用户动作触发,一律算提交意图;卸载没有这种意图,\n * 因此只在草稿与进入编辑时的值确实不同时才提交,不产生空提交。\n * 2. 禁用与只读态——`disabled` / `readonly` 时与 `_onBlur` 一致:不派发提交事件。两者对「已有\n * 草稿」的后果不同,必须分开说:`disabled` 下草稿保留在组件上;`readonly` 下草稿是真的\n * 丢掉——`readonly` 阻止不了先前的输入,而卸载时不会再有 blur 兜底(WebKit 上连 blur\n * 都没有)。可达路径是「可编辑态进入 → 起草稿 → 期间翻 readonly → 卸载」。这里不按取消\n * 处理:cancel 的契约是恢复 `_editBase`,而卸载既没有焦点要交还也没有宿主接收结果,\n * 改成 cancel 还会与「与 `_onBlur` 一致」这条公开承诺相悖。用户看到的是「我打的字没了」,\n * 既没有 change 也没有 cancel。\n *\n * 派发发生在卸载回调内,`change` 沿组合路径向上派发,因此挂在组件自身或任一祖先上的监听\n * 都会执行,**包括已经随宿主一起被卸载的祖先**——派发不要求祖先仍在文档中。这正是虚拟化\n * 场景需要的:消费方的监听器往往就挂在被回收的那一行上。因此监听器不能假定组件此刻仍在\n * 文档里;需要把结果交给宿主树之外的状态时,用 `queueMicrotask` 之类的显式转交。\n *\n * 祖先上的 `display: none` 不是卸载:组件仍在文档中、不派发任何事件(两引擎一致),那种\n * 场合需要消费方主动结束编辑。\n */\n @property({ type: Boolean, reflect: true, attribute: 'commit-on-unmount' }) commitOnUnmount = false\n\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n\n @state() private _value = ''\n\n /**\n * `value` attribute 承载 form reset 的初值,不随当前值反射;property 暴露当前值,\n * 与原生 input 的 value / defaultValue 关系一致。\n */\n @property({ type: String })\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._formAssociation.sync()\n this.requestUpdate('value', old)\n }\n\n @query('.editor') private _editor?: HTMLTextAreaElement\n @query('.text') private _textLayer?: HTMLElement\n\n private _editing = false\n private _editBase = ''\n private _pendingCaret: number | null = null\n private _refocusing = false\n private _resizeObserver: ResizeObserver | null = null\n private readonly _fieldId = createFieldId('web-ui-editable-text')\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => this._value,\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n }\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n constructor() {\n super()\n // focus 不冒泡:宿主监听只在焦点从组件外进入时触发,shadow 内聚焦不会误触\n this.addEventListener('focus', this._onHostFocus)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n /*\n * 卸载没有用户动作作为提交意图(`Enter` / `blur` 都有),所以判据是草稿与进入编辑时的\n * 值是否不同,而不是「是否提交过」——Escape 会把值恢复成 `_editBase`,但那是取消,与\n * 本次卸载无关;一个只聚焦了没打字的会话也不该在消失时凭空产生一次 change。\n *\n * `_isDisabled` 与 `readonly` 两道守卫都与 `_onBlur` 对称:两者都不派发提交事件。`disabled`\n * 必须显式判——`disabled = true` 与 `remove()` 在同一任务里执行时 Lit 更新是微任务,\n * `updated()` 还没跑到(禁用态退出编辑那条分支尚未执行),此时组件仍在编辑态,不判就会\n * 派发一条 blur 路径明确拒绝的 change。`readonly` 不能靠「草稿恒等于基线」兜住:可编辑态\n * 进入并起草稿之后属性才翻成 readonly 的会话,基线仍是进入编辑时的旧值,两条判据都成立\n * 却不该提交(草稿在这次卸载中丢失,理由见 property 的 JSDoc)。\n */\n if (\n this.commitOnUnmount &&\n this._editing &&\n !this._isDisabled &&\n !this.readonly &&\n this._value !== this._editBase\n ) {\n this._commitEditing(false)\n }\n this._releaseEditingKeys()\n this._teardownAutosize()\n }\n\n override connectedCallback() {\n super.connectedCallback()\n /*\n * autosize 的 ResizeObserver 在 disconnectedCallback 被拆掉,搭建若只放在\n * firstUpdated(一生一次),元素断开再重连后 RO 永久丢失、autosize 静默失效。\n * connectedCallback 每次连接都跑:_setupAutosize 自带 teardown,重复进入无副作用。\n * 首连接时渲染尚未发生(_editor 为 null),_autosizeEditor 与 RO 回调都有判空守卫。\n */\n this._setupAutosize()\n // 同类缺口:编辑态被断开时 _releaseEditingKeys 撤了 window 监听,重连后 _editing\n // 仍为 true(blur 取消未必先于断开到达),此时补领,避免重连后按键失灵。\n if (this._editing) this._claimEditingKeys()\n }\n\n override updated() {\n // disabled 时移出 tab 序列;编辑态由 editing attribute 表达,二者互斥\n if (this._isDisabled) this.removeAttribute('tabindex')\n else this.setAttribute('tabindex', '0')\n // 禁用态生效时(属性或 fieldset)退出编辑:值保持当前草稿,不派发提交事件\n if (this._editing && this._isDisabled) this._exitEditing()\n this._autosizeEditor()\n }\n\n private _onHostFocus() {\n if (this._refocusing) {\n this._refocusing = false\n return\n }\n this._enterEditing()\n }\n\n /**\n * pointerdown 时文本层仍是命中目标,此时记录落点;浏览器随后的默认聚焦会触发\n * host focus 进入编辑,偏移在那里应用到 textarea。\n */\n private _onPointerDown(e: PointerEvent) {\n if (this._isDisabled || this._editing || !this._textLayer) return\n this._pendingCaret = caretOffsetFromPoint(this._textLayer, e.clientX, e.clientY)\n }\n\n /** mousedown 默认聚焦被拦截等场景由 click 兜底进入编辑。 */\n private _onClick() {\n if (this._isDisabled || this._editing) return\n this._enterEditing()\n }\n\n /**\n * 公共 API:进入编辑态并全选内容;已在编辑态时只重新全选。\n *\n * `disabled` 时不进入编辑,与 `focus()` 一致。\n */\n select() {\n if (this._isDisabled) return\n if (!this._editing) this._enterEditing()\n const editor = this._editor\n // 全选:末端显式取当前文本长度,覆盖 _enterEditing 落下的光标位置\n editor?.setSelectionRange(0, editor.value.length)\n }\n\n private _enterEditing() {\n if (this._isDisabled || this._editing) return\n this._editing = true\n this._editBase = this._value\n this.toggleAttribute('editing', true)\n this._claimEditingKeys()\n const editor = this._editor\n if (!editor) return\n editor.focus()\n // Tab / 编程式聚焦光标到末尾;指针落点用 pointerdown 记下的偏移\n const offset = this._pendingCaret ?? this._value.length\n this._pendingCaret = null\n const clamped = Math.max(0, Math.min(offset, editor.value.length))\n editor.setSelectionRange(clamped, clamped)\n }\n\n private _exitEditing() {\n if (!this._editing) return\n this._editing = false\n this._releaseEditingKeys()\n this.toggleAttribute('editing', false)\n }\n\n private _onInput() {\n // 原生 input 已 composed 冒泡出 shadow root 且 target 重定向到宿主,无需补发\n const editor = this._editor\n if (this._isDisabled || this.readonly) {\n if (editor && editor.value !== this._value) editor.value = this._value\n return\n }\n this._value = editor?.value ?? ''\n this._formAssociation.sync()\n this._autosizeEditor()\n }\n\n /**\n * blur 提交:与 Enter 同一条提交路径,草稿成为新值并派发 change。\n *\n * 不交还焦点:焦点已被用户移走,抢回宿主会吞掉消费者的目标焦点。\n */\n private _onBlur() {\n if (!this._editing || this._isDisabled) return\n if (this.readonly) {\n this._exitEditing()\n return\n }\n this._commitEditing(false)\n }\n\n /**\n * 提交:草稿成为新值、退出编辑,并恰好派发一次 change。Enter 与 blur 同走这一条路。\n *\n * `returnFocus` 区分两种来路:Enter 主动结束时把焦点交还宿主(标记防重入编辑);\n * blur 是被动失焦,焦点已被用户移走,再抢回宿主会吞掉消费者的目标焦点。\n * 先退出编辑再动焦点:退出时 textarea 隐藏触发的 blur 看到 _editing 已为 false,\n * 不会把这次提交误判成又一次 blur 提交。\n */\n private _commitEditing(returnFocus: boolean) {\n if (!this._editing) return\n this._exitEditing()\n if (returnFocus) this._returnFocusToHost()\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n /**\n * 取消:恢复进入编辑时的值并派发 cancel。仅 Escape 走这一条路径。\n *\n * 调用方(Escape 分支)随后才交还焦点:本方法先摘除编辑态,焦点迁移触发的 blur\n * 到达时 `_editing` 已为 false 而早退,不会把取消误判成 blur 提交。\n */\n private _cancelEditing() {\n if (!this._editing) return\n this._value = this._editBase\n this._formAssociation.sync()\n this._exitEditing()\n /*\n * 重入守卫先于 dispatch 置位:cancel 同步派发,消费者可能在监听器里调\n * el.focus()——那是一次真实的宿主 focus,没有守卫就会重新进入编辑,随后一次\n * blur 便把恢复后的原值当成新草稿提交,用户什么都没改却收到 change。守卫在此\n * 置位后即被该次 focus 消费,与取消后由组件自己交还焦点走同一条早退路径。\n */\n this._refocusing = true\n /*\n * cancel 与原生 <dialog> 的 cancel 同名,而 dialog 的关闭管线就监听这个事件名。\n * 组件被消费方投映进 overlay shadow(drawer/dialog 标题)时,任何冒泡的 cancel——\n * composed 与否都一样,slot 都会把事件带进 shadow 树——都会被那个 dialog 当成\n * 一次关闭请求:issue #159 的实测症状是 drawer 标题聚焦编辑时按 Escape,或点到\n * drawer 别处触发 blur,drawer 跟着编辑一起关。因此只在宿主上派发,不冒泡不组合;\n * 监听挂在组件本身即可(vue @cancel、React addEventListener 均不受影响)。\n * 手法同 checkbox/radio 受管时的事件策略(见各自 handleClick 注释)。\n */\n this.dispatchEvent(new Event('cancel', { bubbles: false, composed: false }))\n }\n\n /**\n * 焦点交还宿主:先标记再聚焦,宿主 focus 到达时标记已消费,不会再次进入编辑;\n * 标记在微任务里清掉,此后的聚焦照常进入编辑。\n */\n private _returnFocusToHost() {\n this._refocusing = true\n this.focus()\n queueMicrotask(() => {\n this._refocusing = false\n })\n }\n\n /**\n * 编辑态按键归属:Enter 提交、Escape 取消。\n *\n * 监听挂在 window 捕获阶段而不是 shadow 内的 textarea 上:消费方(overlay 仲裁者)在\n * document 捕获阶段收 Escape,组件若只在 textarea 上处理,按键先被仲裁者收走,\n * 于是一次 Escape 会同时取消编辑和关闭外层 overlay。window 在 document 上游,\n * stopPropagation 只有挂在这里才拦得住仲裁者。\n */\n private _claimEditingKeys() {\n window.addEventListener('keydown', this._onEditingKeydown, true)\n }\n\n private _releaseEditingKeys() {\n window.removeEventListener('keydown', this._onEditingKeydown, true)\n }\n\n private readonly _onEditingKeydown = (e: KeyboardEvent) => {\n // 输入法组合期间的 Enter/Escape 属于组合会话,交给 IME\n if (e.isComposing) return\n if (!e.composedPath().includes(this)) return\n if (e.key === 'Escape') {\n // 按键本身也被编辑层消费:外层 overlay 不应收到同一次 Escape\n e.preventDefault()\n e.stopPropagation()\n // 先取消(内部摘除编辑态)再交还焦点:focus 触发的 blur 看到 _editing 已为\n // false 而早退,不会把这次取消误判成 blur 提交\n this._cancelEditing()\n this._returnFocusToHost()\n return\n }\n if (e.key === 'Enter') {\n /*\n * Enter 无论是否只读都属于编辑层,消费策略与 Escape 对称:preventDefault\n * 压掉默认行为,stopPropagation 阻止外层表单隐式提交或 overlay 监听收到按键。\n * 只读态只是没有草稿可提交,因此消费后直接返回,不退出编辑、不派发 change。\n */\n e.preventDefault()\n e.stopPropagation()\n if (this.readonly) return\n /*\n * 可编辑态的 Enter 随后提交草稿;外层表单的隐式提交与 overlay 监听不应收到\n * 同一次按键——正如 Escape 属于取消。\n */\n this._commitEditing(true)\n }\n }\n\n private _setupAutosize() {\n this._teardownAutosize()\n // jsdom 等无 ResizeObserver 的环境退化为按渲染 autosize,够用且不抛错\n if (typeof ResizeObserver === 'undefined') {\n this._autosizeEditor()\n return\n }\n this._resizeObserver = new ResizeObserver(() => this._autosizeEditor())\n this._resizeObserver.observe(this)\n this._autosizeEditor()\n }\n\n private _teardownAutosize() {\n this._resizeObserver?.disconnect()\n this._resizeObserver = null\n this._editor?.style.removeProperty('height')\n }\n\n /**\n * 编辑层高度始终跟随自身内容,不依赖文本层折出的行盒。\n *\n * 编辑层绝对定位并用 top/bottom 撑高,`height: auto` 量到的是包含块高度而不是内容高;\n * 先归零再读 scrollHeight,拿到的才是自身内容的高度(含 1px 内边距)。\n * 观察宿主而非编辑层:编辑层在文档流外,改它的高度不会反过来改动宿主尺寸。\n */\n private _autosizeEditor() {\n const editor = this._editor\n if (!editor) return\n const previous = editor.style.height\n editor.style.height = '0px'\n const height = editor.scrollHeight\n editor.style.height = height > 0 ? `${height}px` : previous\n }\n\n private get _displayText(): string {\n if (this._value !== '') return this._value\n if (this.placeholder !== '') return this.placeholder\n return BLANK_GLYPH\n }\n\n override render() {\n return html`\n <div class=\"layers\" @pointerdown=${this._onPointerDown} @click=${this._onClick}>\n <span\n class=${classMap({\n text: true,\n placeholder: this._value === '',\n 'trailing-newline': this._value.endsWith('\\n')\n })}\n >${this._displayText}</span\n >\n <textarea\n id=${this._fieldId}\n class=\"editor\"\n .value=${this._value}\n .placeholder=${this.placeholder}\n ?disabled=${this._isDisabled}\n ?readonly=${this.readonly}\n aria-label=${ifDefined(this.ariaLabel)}\n @input=${this._onInput}\n @blur=${this._onBlur}\n ></textarea>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n cancel: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-editable-text': WebUiEditableText\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["style"],"sources":["../../../src/components/editable-text/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { createFieldId } from '@/shared/form-association/field-id'\n\nimport style from './style.css?inline'\n\n/** 空值且无 placeholder 时保留可点击行盒。 */\nconst BLANK_GLYPH = '\\u200B'\n\n/** 行/字符落点二分的容差(px),吸收次像素与舍入差异。 */\nconst CARET_TOLERANCE = 1\n\n/**\n * 取文本层承载文案的 Text 节点。\n *\n * 绑定表达式位于元素首个位置时,Lit 会在它前面留一个注释标记节点,因此不能用\n * `firstChild`:那会拿到没有布局的注释,Range 量不到任何矩形。\n */\nfunction textNodeOf(layer: HTMLElement): Text | null {\n for (const child of layer.childNodes) {\n if (child instanceof Text) return child\n }\n return null\n}\n\n/**\n * 把视口坐标映射为文本层的字符偏移。\n *\n * `document.caretPositionFromPoint` 不进入 shadow DOM(对 shadow 内容返回 shadow host\n * 之外的节点),因此在文本层上用 Range 空矩形二分:先按 y 选行,再在行内按 x 选字符。\n * 文本层与编辑层同盒同排版,偏移与 textarea 的 selectionStart 一一对应。\n */\nfunction caretOffsetFromPoint(textLayer: HTMLElement, x: number, y: number): number {\n const node = textNodeOf(textLayer)\n if (!node) return 0\n const length = node.data.length\n const range = document.createRange()\n const rectAt = (offset: number): DOMRect => {\n range.setStart(node, offset)\n range.setEnd(node, offset)\n return range.getBoundingClientRect()\n }\n\n // 同一行的盒可能被拆成多个 client rect;按 top 去重得到行列表,取与 y 最近的一行,\n // 距离相等时取更靠下的一行(与浏览器在行间的落点行为一致)。\n const lines: DOMRect[] = []\n for (const rect of textLayer.getClientRects()) {\n if (!lines.some(line => Math.abs(line.top - rect.top) <= CARET_TOLERANCE)) lines.push(rect)\n }\n if (lines.length === 0) return length\n let line = lines[0]\n let nearest = Infinity\n for (const candidate of lines) {\n const distance = Math.abs((candidate.top + candidate.bottom) / 2 - y)\n if (distance <= nearest) {\n nearest = distance\n line = candidate\n }\n }\n\n // 行首:caret top 首次落入本行的最小偏移\n let lo = 0\n let hi = length\n while (lo < hi) {\n const mid = (lo + hi) >> 1\n if (rectAt(mid).top >= line.top - CARET_TOLERANCE) hi = mid\n else lo = mid + 1\n }\n const lineStart = lo\n // 行尾:caret top 仍落在本行的最大偏移\n lo = lineStart\n hi = length\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (rectAt(mid).top <= line.top + CARET_TOLERANCE) lo = mid\n else hi = mid - 1\n }\n const lineEnd = Math.max(lo, lineStart)\n // 行内:caret left 不超过 x 的最大偏移\n lo = lineStart\n hi = lineEnd\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (rectAt(mid).left <= x + CARET_TOLERANCE) lo = mid\n else hi = mid - 1\n }\n return lo\n}\n\n@customElement('web-ui-editable-text')\nexport class WebUiEditableText extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: String, reflect: true }) placeholder = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) readonly = false\n\n /**\n * 卸载时按提交语义结束编辑,默认 false。\n *\n * 跨引擎实测(Chromium 与 WebKit 各一轮)结论**不一致**,这是本属性的主要价值来源:\n *\n * - Chromium:移除正在编辑的组件会向编辑层派发 `blur`,默认行为下 `change` 已照常派发\n * 一次,草稿不丢。blur 与 change 同步排在 `disconnectedCallback` 之后(后者在\n * disconnected 步骤内跑完),卸载因此没拿到一条「排在该消费方状态更新之前」的提交来源。\n * - WebKit(Safari / iOS):移除**不派发 blur**,默认路径什么都不提交,草稿随组件一起丢弃。\n * 这里 blur 兜底不存在,只有显式开启本属性才能保住草稿。\n * - Gecko(Firefox)**未验证**:实测所用机器上没有任何 Firefox 能启动,这里不做断言。把它当作\n * 未知,而不是默认与上面两者之一相同。\n *\n * 所以在 Safari 上这不是可选优化而是必需的:默认值 `false` 对 Safari 用户等于没有兜底,\n * 消费方若依赖「行被回收时草稿不丢」,在 Safari 上必须显式开启本属性。\n *\n * 开启后由 `disconnectedCallback` 复用 `_commitEditing`,与 `Enter`/`blur` 是同一份实现,\n * 卸载不是第三条独立的提交语义。副作用与 `blur` 提交一致:草稿成为新值、退出编辑、\n * 派发一次 `change`(冒泡且组合)。两处与 `blur` 刻意不同:\n *\n * 1. 提交判据——`Enter` 与 `blur` 由用户动作触发,一律算提交意图;卸载没有这种意图,\n * 因此只在草稿与进入编辑时的值确实不同时才提交,不产生空提交。\n * 2. 禁用与只读态——`disabled` / `readonly` 时与 `_onBlur` 一致:不派发提交事件。两者对「已有\n * 草稿」的后果不同,必须分开说:`disabled` 下草稿保留在组件上;`readonly` 下草稿是真的\n * 丢掉——`readonly` 阻止不了先前的输入,而卸载时不会再有 blur 兜底(WebKit 上连 blur\n * 都没有)。可达路径是「可编辑态进入 → 起草稿 → 期间翻 readonly → 卸载」。这里不按取消\n * 处理:cancel 的契约是恢复 `_editBase`,而卸载既没有焦点要交还也没有宿主接收结果,\n * 改成 cancel 还会与「与 `_onBlur` 一致」这条公开承诺相悖。用户看到的是「我打的字没了」,\n * 既没有 change 也没有 cancel。\n *\n * 派发发生在卸载回调内,`change` 沿组合路径向上派发,因此挂在组件自身或任一祖先上的监听\n * 都会执行,**包括已经随宿主一起被卸载的祖先**——派发不要求祖先仍在文档中。这正是虚拟化\n * 场景需要的:消费方的监听器往往就挂在被回收的那一行上。因此监听器不能假定组件此刻仍在\n * 文档里;需要把结果交给宿主树之外的状态时,用 `queueMicrotask` 之类的显式转交。\n *\n * 祖先上的 `display: none` 不是卸载:组件仍在文档中、不派发任何事件(两引擎一致),那种\n * 场合需要消费方主动结束编辑。\n */\n @property({ type: Boolean, reflect: true, attribute: 'commit-on-unmount' }) commitOnUnmount = false\n\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n\n @state() private _value = ''\n\n /**\n * `value` attribute 承载 form reset 的初值,不随当前值反射;property 暴露当前值,\n * 与原生 input 的 value / defaultValue 关系一致。\n */\n @property({ type: String })\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._formAssociation.sync()\n this.requestUpdate('value', old)\n }\n\n @query('.editor') private _editor?: HTMLTextAreaElement\n @query('.text') private _textLayer?: HTMLElement\n\n private _editing = false\n private _editBase = ''\n private _pendingCaret: number | null = null\n private _refocusing = false\n private _resizeObserver: ResizeObserver | null = null\n private readonly _fieldId = createFieldId('web-ui-editable-text')\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => this._value,\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n }\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n constructor() {\n super()\n // focus 不冒泡:宿主监听只在焦点从组件外进入时触发,shadow 内聚焦不会误触\n this.addEventListener('focus', this._onHostFocus)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n /*\n * 卸载没有用户动作作为提交意图(`Enter` / `blur` 都有),所以判据是草稿与进入编辑时的\n * 值是否不同,而不是「是否提交过」——Escape 会把值恢复成 `_editBase`,但那是取消,与\n * 本次卸载无关;一个只聚焦了没打字的会话也不该在消失时凭空产生一次 change。\n *\n * `_isDisabled` 与 `readonly` 两道守卫都与 `_onBlur` 对称:两者都不派发提交事件。`disabled`\n * 必须显式判——`disabled = true` 与 `remove()` 在同一任务里执行时 Lit 更新是微任务,\n * `updated()` 还没跑到(禁用态退出编辑那条分支尚未执行),此时组件仍在编辑态,不判就会\n * 派发一条 blur 路径明确拒绝的 change。`readonly` 不能靠「草稿恒等于基线」兜住:可编辑态\n * 进入并起草稿之后属性才翻成 readonly 的会话,基线仍是进入编辑时的旧值,两条判据都成立\n * 却不该提交(草稿在这次卸载中丢失,理由见 property 的 JSDoc)。\n */\n if (\n this.commitOnUnmount &&\n this._editing &&\n !this._isDisabled &&\n !this.readonly &&\n this._value !== this._editBase\n ) {\n this._commitEditing(false)\n }\n this._releaseEditingKeys()\n this._teardownAutosize()\n }\n\n override connectedCallback() {\n super.connectedCallback()\n /*\n * autosize 的 ResizeObserver 在 disconnectedCallback 被拆掉,搭建若只放在\n * firstUpdated(一生一次),元素断开再重连后 RO 永久丢失、autosize 静默失效。\n * connectedCallback 每次连接都跑:_setupAutosize 自带 teardown,重复进入无副作用。\n * 首连接时渲染尚未发生(_editor 为 null),_autosizeEditor 与 RO 回调都有判空守卫。\n */\n this._setupAutosize()\n // 同类缺口:编辑态被断开时 _releaseEditingKeys 撤了 window 监听,重连后 _editing\n // 仍为 true(blur 取消未必先于断开到达),此时补领,避免重连后按键失灵。\n if (this._editing) this._claimEditingKeys()\n }\n\n override updated() {\n // disabled 时移出 tab 序列;编辑态由 editing attribute 表达,二者互斥\n if (this._isDisabled) this.removeAttribute('tabindex')\n else this.setAttribute('tabindex', '0')\n // 禁用态生效时(属性或 fieldset)退出编辑:值保持当前草稿,不派发提交事件\n if (this._editing && this._isDisabled) this._exitEditing()\n this._autosizeEditor()\n }\n\n private _onHostFocus() {\n if (this._refocusing) {\n this._refocusing = false\n return\n }\n this._enterEditing()\n }\n\n /**\n * pointerdown 时文本层仍是命中目标,此时记录落点;浏览器随后的默认聚焦会触发\n * host focus 进入编辑,偏移在那里应用到 textarea。\n */\n private _onPointerDown(e: PointerEvent) {\n if (this._isDisabled || this._editing || !this._textLayer) return\n this._pendingCaret = caretOffsetFromPoint(this._textLayer, e.clientX, e.clientY)\n }\n\n /** mousedown 默认聚焦被拦截等场景由 click 兜底进入编辑。 */\n private _onClick() {\n if (this._isDisabled || this._editing) return\n this._enterEditing()\n }\n\n /**\n * 公共 API:进入编辑态并全选内容;已在编辑态时只重新全选。\n *\n * `disabled` 时不进入编辑,与 `focus()` 一致。\n */\n select() {\n if (this._isDisabled) return\n if (!this._editing) this._enterEditing()\n const editor = this._editor\n // 全选:末端显式取当前文本长度,覆盖 _enterEditing 落下的光标位置\n editor?.setSelectionRange(0, editor.value.length)\n }\n\n private _enterEditing() {\n if (this._isDisabled || this._editing) return\n this._editing = true\n this._editBase = this._value\n this.toggleAttribute('editing', true)\n this._claimEditingKeys()\n const editor = this._editor\n if (!editor) return\n editor.focus()\n // Tab / 编程式聚焦光标到末尾;指针落点用 pointerdown 记下的偏移\n const offset = this._pendingCaret ?? this._value.length\n this._pendingCaret = null\n const clamped = Math.max(0, Math.min(offset, editor.value.length))\n editor.setSelectionRange(clamped, clamped)\n }\n\n private _exitEditing() {\n if (!this._editing) return\n this._editing = false\n this._releaseEditingKeys()\n this.toggleAttribute('editing', false)\n }\n\n private _onInput() {\n // 原生 input 已 composed 冒泡出 shadow root 且 target 重定向到宿主,无需补发\n const editor = this._editor\n if (this._isDisabled || this.readonly) {\n if (editor && editor.value !== this._value) editor.value = this._value\n return\n }\n this._value = editor?.value ?? ''\n this._formAssociation.sync()\n this._autosizeEditor()\n }\n\n /**\n * blur 提交:与 Enter 同一条提交路径,草稿成为新值并派发 change。\n *\n * 不交还焦点:焦点已被用户移走,抢回宿主会吞掉消费者的目标焦点。\n */\n private _onBlur() {\n if (!this._editing || this._isDisabled) return\n if (this.readonly) {\n this._exitEditing()\n return\n }\n this._commitEditing(false)\n }\n\n /**\n * 提交:草稿成为新值、退出编辑,并恰好派发一次 change。Enter 与 blur 同走这一条路。\n *\n * `returnFocus` 区分两种来路:Enter 主动结束时把焦点交还宿主(标记防重入编辑);\n * blur 是被动失焦,焦点已被用户移走,再抢回宿主会吞掉消费者的目标焦点。\n * 先退出编辑再动焦点:退出时 textarea 隐藏触发的 blur 看到 _editing 已为 false,\n * 不会把这次提交误判成又一次 blur 提交。\n */\n private _commitEditing(returnFocus: boolean) {\n if (!this._editing) return\n this._exitEditing()\n if (returnFocus) this._returnFocusToHost()\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n /**\n * 取消:恢复进入编辑时的值并派发 cancel。仅 Escape 走这一条路径。\n *\n * 调用方(Escape 分支)随后才交还焦点:本方法先摘除编辑态,焦点迁移触发的 blur\n * 到达时 `_editing` 已为 false 而早退,不会把取消误判成 blur 提交。\n */\n private _cancelEditing() {\n if (!this._editing) return\n this._value = this._editBase\n this._formAssociation.sync()\n this._exitEditing()\n /*\n * 重入守卫先于 dispatch 置位:cancel 同步派发,消费者可能在监听器里调\n * el.focus()——那是一次真实的宿主 focus,没有守卫就会重新进入编辑,随后一次\n * blur 便把恢复后的原值当成新草稿提交,用户什么都没改却收到 change。守卫在此\n * 置位后即被该次 focus 消费,与取消后由组件自己交还焦点走同一条早退路径。\n */\n this._refocusing = true\n /*\n * cancel 与原生 <dialog> 的 cancel 同名,而 dialog 的关闭管线就监听这个事件名。\n * 组件被消费方投映进 overlay shadow(drawer/dialog 标题)时,任何冒泡的 cancel——\n * composed 与否都一样,slot 都会把事件带进 shadow 树——都会被那个 dialog 当成\n * 一次关闭请求:issue #159 的实测症状是 drawer 标题聚焦编辑时按 Escape,或点到\n * drawer 别处触发 blur,drawer 跟着编辑一起关。因此只在宿主上派发,不冒泡不组合;\n * 监听挂在组件本身即可(vue @cancel、React addEventListener 均不受影响)。\n * 手法同 checkbox/radio 受管时的事件策略(见各自 handleClick 注释)。\n */\n this.dispatchEvent(new Event('cancel', { bubbles: false, composed: false }))\n }\n\n /**\n * 焦点交还宿主:先标记再聚焦,宿主 focus 到达时标记已消费,不会再次进入编辑;\n * 标记在微任务里清掉,此后的聚焦照常进入编辑。\n */\n private _returnFocusToHost() {\n this._refocusing = true\n this.focus()\n queueMicrotask(() => {\n this._refocusing = false\n })\n }\n\n /**\n * 编辑态按键归属:Enter 提交、Escape 取消。\n *\n * 监听挂在 window 捕获阶段而不是 shadow 内的 textarea 上:消费方(overlay 仲裁者)在\n * document 捕获阶段收 Escape,组件若只在 textarea 上处理,按键先被仲裁者收走,\n * 于是一次 Escape 会同时取消编辑和关闭外层 overlay。window 在 document 上游,\n * stopPropagation 只有挂在这里才拦得住仲裁者。\n */\n private _claimEditingKeys() {\n window.addEventListener('keydown', this._onEditingKeydown, true)\n }\n\n private _releaseEditingKeys() {\n window.removeEventListener('keydown', this._onEditingKeydown, true)\n }\n\n private readonly _onEditingKeydown = (e: KeyboardEvent) => {\n // 输入法组合期间的 Enter/Escape 属于组合会话,交给 IME\n if (e.isComposing) return\n if (!e.composedPath().includes(this)) return\n if (e.key === 'Escape') {\n // 按键本身也被编辑层消费:外层 overlay 不应收到同一次 Escape\n e.preventDefault()\n e.stopPropagation()\n // 先取消(内部摘除编辑态)再交还焦点:focus 触发的 blur 看到 _editing 已为\n // false 而早退,不会把这次取消误判成 blur 提交\n this._cancelEditing()\n this._returnFocusToHost()\n return\n }\n if (e.key === 'Enter') {\n /*\n * Enter 无论是否只读都属于编辑层,消费策略与 Escape 对称:preventDefault\n * 压掉默认行为,stopPropagation 阻止外层表单隐式提交或 overlay 监听收到按键。\n * 只读态只是没有草稿可提交,因此消费后直接返回,不退出编辑、不派发 change。\n */\n e.preventDefault()\n e.stopPropagation()\n if (this.readonly) return\n /*\n * 可编辑态的 Enter 随后提交草稿;外层表单的隐式提交与 overlay 监听不应收到\n * 同一次按键——正如 Escape 属于取消。\n */\n this._commitEditing(true)\n }\n }\n\n private _setupAutosize() {\n this._teardownAutosize()\n // jsdom 等无 ResizeObserver 的环境退化为按渲染 autosize,够用且不抛错\n if (typeof ResizeObserver === 'undefined') {\n this._autosizeEditor()\n return\n }\n this._resizeObserver = new ResizeObserver(() => this._autosizeEditor())\n this._resizeObserver.observe(this)\n this._autosizeEditor()\n }\n\n private _teardownAutosize() {\n this._resizeObserver?.disconnect()\n this._resizeObserver = null\n this._editor?.style.removeProperty('height')\n }\n\n /**\n * 编辑层高度始终跟随自身内容,不依赖文本层折出的行盒。\n *\n * 编辑层绝对定位并用 top/bottom 撑高,`height: auto` 量到的是包含块高度而不是内容高;\n * 先归零再读 scrollHeight,拿到的才是自身内容的高度(含 1px 内边距)。\n * 观察宿主而非编辑层:编辑层在文档流外,改它的高度不会反过来改动宿主尺寸。\n */\n private _autosizeEditor() {\n const editor = this._editor\n if (!editor) return\n const previous = editor.style.height\n editor.style.height = '0px'\n const height = editor.scrollHeight\n editor.style.height = height > 0 ? `${height}px` : previous\n }\n\n private get _displayText(): string {\n if (this._value !== '') return this._value\n if (this.placeholder !== '') return this.placeholder\n return BLANK_GLYPH\n }\n\n override render() {\n return html`\n <div class=\"layers\" @pointerdown=${this._onPointerDown} @click=${this._onClick}>\n <span\n class=${classMap({\n text: true,\n placeholder: this._value === '',\n 'trailing-newline': this._value.endsWith('\\n')\n })}\n >${this._displayText}</span\n >\n <textarea\n id=${this._fieldId}\n class=\"editor\"\n .value=${this._value}\n .placeholder=${this.placeholder}\n ?disabled=${this._isDisabled}\n ?readonly=${this.readonly}\n aria-label=${ifDefined(this.ariaLabel)}\n @input=${this._onInput}\n @blur=${this._onBlur}\n ></textarea>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n cancel: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-editable-text': WebUiEditableText\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
export { e as default };
|
|
1
|
+
// src/components/editable-text/style.css?inline
|
|
2
|
+
var style_default = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}.layers{display:block;position:relative}.text,.editor{overflow-wrap:var(--wui-editable-text-overflow-wrap,anywhere);white-space:var(--wui-editable-text-white-space,pre-wrap)}.text{display:inline}.text.trailing-newline:after{content:\"\";width:0;display:inline-block}.placeholder{color:var(--wui-color-text-secondary,#6a6a6a)}.editor{resize:none;font:inherit;line-height:inherit;color:inherit;text-align:inherit;text-transform:inherit;letter-spacing:inherit;word-break:inherit;appearance:none;visibility:hidden;caret-color:var(--wui-color-accent,#0071e3);background:0 0;border:0;outline:none;margin:0;padding:1px;position:absolute;inset:-1px;overflow:hidden}.editor::placeholder{color:var(--wui-color-text-secondary,#6a6a6a)}:host([editing]) .editor{visibility:visible;min-width:1ch}:host([editing]) .text{visibility:hidden}:host([disabled]){cursor:not-allowed}\n";
|
|
3
|
+
export { style_default as default };
|
|
5
4
|
|
|
6
5
|
//# sourceMappingURL=style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/editable-text/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/* 组件对外表现为同级 span:行内级盒子,排版与颜色全部继承外部上下文。\n :host 只设 display(ADR-0005),其余样式在 shadow root 内。 */\n:host {\n display: inline-block;\n}\n\n/* 文本层与编辑层共用的排版盒:编辑层 absolute 定位覆盖它,切换只改可见性,\n 因此文字态与编辑态逐像素同盒。 */\n.layers {\n position: relative;\n display: block;\n}\n\n.text,\n.editor {\n /* 长无空格串两层都必须能断:文本层若只继承宿主默认的 normal,长字母数字串不\n 截断、直接溢出宿主盒(文字态),而编辑层在盒内裁剪(编辑态),两层断行\n 不一致。默认 anywhere:仅在单词放不下时断,且参与 min-content 计算,收缩\n 上下文(flex 项 min-width:0)里长串也不会撑爆宿主;两层取同一变量,外部\n 覆盖时仍保持一致。 */\n overflow-wrap: var(--wui-editable-text-overflow-wrap, anywhere);\n\n /* 多行编辑要求换行符成行,但 pre-wrap 只能落在文本层上:模板里元素之间的空白\n 文本节点若被 pre-wrap 保留,会各自生成幻影行盒,把文本层顶偏、盒高翻倍,\n 文字态与编辑态随之不再同盒。这里保持 .layers 为默认 normal 让空白 collapse,\n 两层取同一变量,外部覆盖(如 nowrap)时仍保持一致。 */\n white-space: var(--wui-editable-text-white-space, pre-wrap);\n}\n\n.text {\n display: inline;\n}\n\n/* pre-wrap 不为文本节点末尾的换行留下行盒;空的零宽行内块触发末行排版,\n 不向文本节点添加字符,因此选择、复制与 value 保持一致。 */\n.text.trailing-newline::after {\n content: '';\n display: inline-block;\n width: 0;\n}\n\n.placeholder {\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n/* 原生控件 reset:不贡献尺寸、无边框背景描边、不可手拖改变大小 */\n.editor {\n resize: none;\n\n position: absolute;\n\n /* 四边各外扩 1px,再用 1px 内边距把文本起点与换行宽度拉回内容盒。\n 两层必须同盒,但盒的边界同时也是原生控件的裁剪边界:文本层的字形会按\n 边距溢出内容盒半个像素左右,紧凑行高下 textarea 内部内容也会比内容盒高\n 出 1px。裁剪盒若与内容盒重合,这些墨色只存在于文字态,编辑态被裁掉或顶偏,\n 两态逐像素比对就对不上;外扩 1px 后编辑层的裁剪盒覆盖文本层的墨色范围。 */\n inset: -1px;\n\n overflow: hidden;\n\n margin: 0;\n padding: 1px;\n border: 0;\n\n /* 原生控件不继承排版:显式继承让编辑层与文本层共用同一套字体度量 */\n font: inherit;\n line-height: inherit;\n color: inherit;\n text-align: inherit;\n text-transform: inherit;\n letter-spacing: inherit;\n word-break: inherit;\n\n appearance: none;\n visibility: hidden;\n background: transparent;\n outline: none;\n\n /* 光标颜色组件级默认:跟随共享语义 token,消费方在宿主或任意祖先上设\n --wui-color-accent 即可覆盖(自定义属性穿透 shadow 边界继承);\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/editable-text/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/* 组件对外表现为同级 span:行内级盒子,排版与颜色全部继承外部上下文。\n :host 只设 display(ADR-0005),其余样式在 shadow root 内。 */\n:host {\n display: inline-block;\n}\n\n/* 文本层与编辑层共用的排版盒:编辑层 absolute 定位覆盖它,切换只改可见性,\n 因此文字态与编辑态逐像素同盒。 */\n.layers {\n position: relative;\n display: block;\n}\n\n.text,\n.editor {\n /* 长无空格串两层都必须能断:文本层若只继承宿主默认的 normal,长字母数字串不\n 截断、直接溢出宿主盒(文字态),而编辑层在盒内裁剪(编辑态),两层断行\n 不一致。默认 anywhere:仅在单词放不下时断,且参与 min-content 计算,收缩\n 上下文(flex 项 min-width:0)里长串也不会撑爆宿主;两层取同一变量,外部\n 覆盖时仍保持一致。 */\n overflow-wrap: var(--wui-editable-text-overflow-wrap, anywhere);\n\n /* 多行编辑要求换行符成行,但 pre-wrap 只能落在文本层上:模板里元素之间的空白\n 文本节点若被 pre-wrap 保留,会各自生成幻影行盒,把文本层顶偏、盒高翻倍,\n 文字态与编辑态随之不再同盒。这里保持 .layers 为默认 normal 让空白 collapse,\n 两层取同一变量,外部覆盖(如 nowrap)时仍保持一致。 */\n white-space: var(--wui-editable-text-white-space, pre-wrap);\n}\n\n.text {\n display: inline;\n}\n\n/* pre-wrap 不为文本节点末尾的换行留下行盒;空的零宽行内块触发末行排版,\n 不向文本节点添加字符,因此选择、复制与 value 保持一致。 */\n.text.trailing-newline::after {\n content: '';\n display: inline-block;\n width: 0;\n}\n\n.placeholder {\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n/* 原生控件 reset:不贡献尺寸、无边框背景描边、不可手拖改变大小 */\n.editor {\n resize: none;\n\n position: absolute;\n\n /* 四边各外扩 1px,再用 1px 内边距把文本起点与换行宽度拉回内容盒。\n 两层必须同盒,但盒的边界同时也是原生控件的裁剪边界:文本层的字形会按\n 边距溢出内容盒半个像素左右,紧凑行高下 textarea 内部内容也会比内容盒高\n 出 1px。裁剪盒若与内容盒重合,这些墨色只存在于文字态,编辑态被裁掉或顶偏,\n 两态逐像素比对就对不上;外扩 1px 后编辑层的裁剪盒覆盖文本层的墨色范围。 */\n inset: -1px;\n\n overflow: hidden;\n\n margin: 0;\n padding: 1px;\n border: 0;\n\n /* 原生控件不继承排版:显式继承让编辑层与文本层共用同一套字体度量 */\n font: inherit;\n line-height: inherit;\n color: inherit;\n text-align: inherit;\n text-transform: inherit;\n letter-spacing: inherit;\n word-break: inherit;\n\n appearance: none;\n visibility: hidden;\n background: transparent;\n outline: none;\n\n /* 光标颜色组件级默认:跟随共享语义 token,消费方在宿主或任意祖先上设\n --wui-color-accent 即可覆盖(自定义属性穿透 shadow 边界继承);\n 未设 --wui-color-accent 的消费方拿到的是浏览器默认黑。 */\n caret-color: var(--wui-color-accent, #0071e3);\n\n &::placeholder {\n color: var(--wui-color-text-secondary, #6a6a6a);\n }\n}\n\n/* 可见性切换:文字态隐藏编辑层、编辑态显露;盒模型、滚动与换行不随之变化 */\n:host([editing]) .editor {\n /* 空内容时宿主可能被收缩到 0 宽:行内级盒子配上零宽 placeholder,收缩上下文(flex 项\n min-width:0、表格单元格等)里就量不到宽度,编辑层随之没有可绘制光标的地盘,\n 清空全部内容后光标消失。留一个字符宽,保证空草稿下光标仍然可见。\n 规则落在 shadow 内:宿主上的 min-width 属于外层文档样式,会盖过 :host 声明。 */\n min-width: 1ch;\n visibility: visible;\n}\n\n/* 编辑态隐藏文本层:两层同盒同排版,若同时可见会把同一份文字画两遍,\n 抗锯齿边缘的墨色会加重,破坏文字态/编辑态的逐像素一致。 */\n:host([editing]) .text {\n visibility: hidden;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../icon/index.js";
|
|
2
|
+
import { LitElement } from "lit";
|
|
2
3
|
/**
|
|
3
4
|
* 空态图形区。
|
|
4
5
|
*
|
|
5
|
-
* 默认图形直接渲染成 `svg
|
|
6
|
+
* 默认图形直接渲染成 `svg`,不包 `web-ui-icon`:`web-ui-icon` 的边长是 JS 属性
|
|
6
7
|
* (`.size`),CSS 变量驱动不了它,而空态的默认图形是固定资产,没有必要为了几个像素
|
|
7
8
|
* 去读 computed style 再回写属性。样式因此全部落在 CSS 上,调用方换尺寸只写变量。
|
|
8
9
|
*
|
|
@@ -10,19 +11,20 @@ import { LitElement } from 'lit';
|
|
|
10
11
|
* (`@greypan/web-ui/icons`),组件注册由这里提供。
|
|
11
12
|
*/
|
|
12
13
|
export declare class WebUiEmpty extends LitElement {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
static styles: import("lit").CSSResult[];
|
|
15
|
+
title: string;
|
|
16
|
+
description: string;
|
|
17
|
+
private _hasTitleSlot;
|
|
18
|
+
private _hasDescriptionSlot;
|
|
19
|
+
private _hasActionSlot;
|
|
20
|
+
connectedCallback(): void;
|
|
21
|
+
private _syncSlotContent;
|
|
22
|
+
private _hasAssignedContent;
|
|
23
|
+
render(): import("lit").TemplateResult<1>;
|
|
23
24
|
}
|
|
24
25
|
declare global {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
interface HTMLElementTagNameMap {
|
|
27
|
+
'web-ui-empty': WebUiEmpty;
|
|
28
|
+
}
|
|
28
29
|
}
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/empty/index.ts"],"mappings":";;;;;;;;;;;;qBAmCa,mBAAmB;SACd,sBAAM;EAE8B;EAET;UAE1B;UACA;UACA;EAER;UAKD;UAMA;EAOC,wBAAM;;QAuCT;YACI;IACR,gBAAgB"}
|
|
@@ -1,58 +1,83 @@
|
|
|
1
|
-
import
|
|
1
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
2
2
|
import "../icon/index.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { LitElement
|
|
6
|
-
import { customElement
|
|
7
|
-
import { classMap
|
|
8
|
-
import { unsafeSVG
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
import andrsrxn_inbox_default from "../../icons/generated/andrsrxn-inbox.js";
|
|
4
|
+
import style_default from "./style.js";
|
|
5
|
+
import { LitElement, html, unsafeCSS } from "lit";
|
|
6
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
7
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
8
|
+
import { unsafeSVG } from "lit/directives/unsafe-svg.js";
|
|
9
|
+
// src/components/empty/index.ts
|
|
10
|
+
/**
|
|
11
|
+
* Iconify 规范里画布缺省按 16 计(见 @iconify/types README)。生成资产自带尺寸,
|
|
12
|
+
* 这条兜底服务的是把默认图形换成手写 IconifyIcon 对象的场景。
|
|
13
|
+
*/
|
|
14
|
+
const ICONIFY_DEFAULT_CANVAS = 16;
|
|
15
|
+
/**
|
|
16
|
+
* SVG 的 width/height 属性值,与 CSS 里 `--wui-empty-icon-size` 的默认值一致。
|
|
17
|
+
* 只负责首帧与 CSS 未生效时的高度,实际边长由 CSS 变量决定。
|
|
18
|
+
*/
|
|
19
|
+
const FALLBACK_ICON_SIZE = 40;
|
|
20
|
+
let WebUiEmpty = class WebUiEmpty extends LitElement {
|
|
21
|
+
constructor(..._args) {
|
|
22
|
+
super(..._args);
|
|
23
|
+
this.title = "";
|
|
24
|
+
this.description = "";
|
|
25
|
+
this._hasTitleSlot = false;
|
|
26
|
+
this._hasDescriptionSlot = false;
|
|
27
|
+
this._hasActionSlot = false;
|
|
28
|
+
this._syncSlotContent = () => {
|
|
29
|
+
this._hasTitleSlot = this._hasAssignedContent();
|
|
30
|
+
this._hasDescriptionSlot = this._hasAssignedContent("description");
|
|
31
|
+
this._hasActionSlot = this._hasAssignedContent("action");
|
|
14
32
|
};
|
|
15
33
|
}
|
|
16
34
|
static {
|
|
17
|
-
this.styles = [
|
|
35
|
+
this.styles = [unsafeCSS(style_default)];
|
|
18
36
|
}
|
|
19
37
|
connectedCallback() {
|
|
20
|
-
super.connectedCallback()
|
|
38
|
+
super.connectedCallback();
|
|
39
|
+
this._syncSlotContent();
|
|
21
40
|
}
|
|
22
|
-
_hasAssignedContent(
|
|
23
|
-
return [...this.childNodes].some((
|
|
41
|
+
_hasAssignedContent(slotName) {
|
|
42
|
+
return [...this.childNodes].some((node) => {
|
|
43
|
+
if (node instanceof HTMLElement && (node.getAttribute("slot") ?? "") === (slotName ?? "")) return true;
|
|
44
|
+
return !slotName && node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim());
|
|
45
|
+
});
|
|
24
46
|
}
|
|
25
47
|
render() {
|
|
26
|
-
|
|
27
|
-
|
|
48
|
+
const showTitle = this._hasTitleSlot || Boolean(this.title);
|
|
49
|
+
const showDescription = this._hasDescriptionSlot || Boolean(this.description);
|
|
50
|
+
const glyph = andrsrxn_inbox_default;
|
|
51
|
+
const viewBox = `${glyph.left ?? 0} ${glyph.top ?? 0} ${glyph.width ?? ICONIFY_DEFAULT_CANVAS} ${glyph.height ?? ICONIFY_DEFAULT_CANVAS}`;
|
|
52
|
+
return html`
|
|
28
53
|
<section class="empty">
|
|
29
54
|
<div class="empty-icon" aria-hidden="true">
|
|
30
55
|
<slot name="icon">
|
|
31
56
|
<svg
|
|
32
57
|
class="empty-glyph"
|
|
33
|
-
viewBox="${
|
|
34
|
-
width="${
|
|
35
|
-
height="${
|
|
58
|
+
viewBox="${viewBox}"
|
|
59
|
+
width="${FALLBACK_ICON_SIZE}"
|
|
60
|
+
height="${FALLBACK_ICON_SIZE}"
|
|
36
61
|
aria-hidden="true"
|
|
37
62
|
>
|
|
38
|
-
${
|
|
63
|
+
${unsafeSVG(andrsrxn_inbox_default.body)}
|
|
39
64
|
</svg>
|
|
40
65
|
</slot>
|
|
41
66
|
</div>
|
|
42
|
-
<div class=${
|
|
43
|
-
"empty-title":
|
|
44
|
-
"is-hidden": !
|
|
67
|
+
<div class=${classMap({
|
|
68
|
+
"empty-title": true,
|
|
69
|
+
"is-hidden": !showTitle
|
|
45
70
|
})}>
|
|
46
71
|
<slot @slotchange=${this._syncSlotContent}>${this.title}</slot>
|
|
47
72
|
</div>
|
|
48
|
-
<div class=${
|
|
49
|
-
"empty-description":
|
|
50
|
-
"is-hidden": !
|
|
73
|
+
<div class=${classMap({
|
|
74
|
+
"empty-description": true,
|
|
75
|
+
"is-hidden": !showDescription
|
|
51
76
|
})}>
|
|
52
77
|
<slot name="description" @slotchange=${this._syncSlotContent}>${this.description}</slot>
|
|
53
78
|
</div>
|
|
54
|
-
<div class=${
|
|
55
|
-
"empty-action":
|
|
79
|
+
<div class=${classMap({
|
|
80
|
+
"empty-action": true,
|
|
56
81
|
"is-hidden": !this._hasActionSlot
|
|
57
82
|
})}>
|
|
58
83
|
<slot name="action" @slotchange=${this._syncSlotContent}></slot>
|
|
@@ -61,14 +86,18 @@ var d = 16, f = 40, p = class extends r {
|
|
|
61
86
|
`;
|
|
62
87
|
}
|
|
63
88
|
};
|
|
64
|
-
|
|
89
|
+
__decorate([property({
|
|
65
90
|
type: String,
|
|
66
|
-
reflect:
|
|
67
|
-
})],
|
|
91
|
+
reflect: true
|
|
92
|
+
})], WebUiEmpty.prototype, "title", void 0);
|
|
93
|
+
__decorate([property({
|
|
68
94
|
type: String,
|
|
69
|
-
reflect:
|
|
70
|
-
})],
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
reflect: true
|
|
96
|
+
})], WebUiEmpty.prototype, "description", void 0);
|
|
97
|
+
__decorate([state()], WebUiEmpty.prototype, "_hasTitleSlot", void 0);
|
|
98
|
+
__decorate([state()], WebUiEmpty.prototype, "_hasDescriptionSlot", void 0);
|
|
99
|
+
__decorate([state()], WebUiEmpty.prototype, "_hasActionSlot", void 0);
|
|
100
|
+
WebUiEmpty = __decorate([customElement("web-ui-empty")], WebUiEmpty);
|
|
101
|
+
export { WebUiEmpty };
|
|
73
102
|
|
|
74
103
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/empty/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport type { IconifyIcon } from '@iconify/types'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js'\n\nimport { andrsrxnInbox } from '@/icons'\n\nimport style from './style.css?inline'\n\n/**\n * Iconify 规范里画布缺省按 16 计(见 @iconify/types README)。生成资产自带尺寸,\n * 这条兜底服务的是把默认图形换成手写 IconifyIcon 对象的场景。\n */\nconst ICONIFY_DEFAULT_CANVAS = 16\n\n/**\n * SVG 的 width/height 属性值,与 CSS 里 `--wui-empty-icon-size` 的默认值一致。\n * 只负责首帧与 CSS 未生效时的高度,实际边长由 CSS 变量决定。\n */\nconst FALLBACK_ICON_SIZE = 40\n\n/**\n * 空态图形区。\n *\n * 默认图形直接渲染成 `svg
|
|
1
|
+
{"version":3,"file":"index.js","names":["style","andrsrxnInbox"],"sources":["../../../src/components/empty/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport type { IconifyIcon } from '@iconify/types'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js'\n\nimport { andrsrxnInbox } from '@/icons'\n\nimport style from './style.css?inline'\n\n/**\n * Iconify 规范里画布缺省按 16 计(见 @iconify/types README)。生成资产自带尺寸,\n * 这条兜底服务的是把默认图形换成手写 IconifyIcon 对象的场景。\n */\nconst ICONIFY_DEFAULT_CANVAS = 16\n\n/**\n * SVG 的 width/height 属性值,与 CSS 里 `--wui-empty-icon-size` 的默认值一致。\n * 只负责首帧与 CSS 未生效时的高度,实际边长由 CSS 变量决定。\n */\nconst FALLBACK_ICON_SIZE = 40\n\n/**\n * 空态图形区。\n *\n * 默认图形直接渲染成 `svg`,不包 `web-ui-icon`:`web-ui-icon` 的边长是 JS 属性\n * (`.size`),CSS 变量驱动不了它,而空态的默认图形是固定资产,没有必要为了几个像素\n * 去读 computed style 再回写属性。样式因此全部落在 CSS 上,调用方换尺寸只写变量。\n *\n * 副作用导入 `@/components/icon` 保留:`icon` 插槽的既有写法只 import 图标数据\n * (`@greypan/web-ui/icons`),组件注册由这里提供。\n */\n@customElement('web-ui-empty')\nexport class WebUiEmpty extends LitElement {\n static override styles = [unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) override title = ''\n\n @property({ type: String, reflect: true }) description = ''\n\n @state() private _hasTitleSlot = false\n @state() private _hasDescriptionSlot = false\n @state() private _hasActionSlot = false\n\n override connectedCallback() {\n super.connectedCallback()\n this._syncSlotContent()\n }\n\n private _syncSlotContent = () => {\n this._hasTitleSlot = this._hasAssignedContent()\n this._hasDescriptionSlot = this._hasAssignedContent('description')\n this._hasActionSlot = this._hasAssignedContent('action')\n }\n\n private _hasAssignedContent(slotName?: string): boolean {\n return [...this.childNodes].some(node => {\n if (node instanceof HTMLElement && (node.getAttribute('slot') ?? '') === (slotName ?? '')) return true\n return !slotName && node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())\n })\n }\n\n override render() {\n const showTitle = this._hasTitleSlot || Boolean(this.title)\n const showDescription = this._hasDescriptionSlot || Boolean(this.description)\n\n // 生成物只写下有值的字段,`left` / `top` 缺省即 0(Iconify 规范),所以按 IconifyIcon 读。\n const glyph: IconifyIcon = andrsrxnInbox\n const viewBox = `${glyph.left ?? 0} ${glyph.top ?? 0} ${glyph.width ?? ICONIFY_DEFAULT_CANVAS} ${\n glyph.height ?? ICONIFY_DEFAULT_CANVAS\n }`\n\n return html`\n <section class=\"empty\">\n <div class=\"empty-icon\" aria-hidden=\"true\">\n <slot name=\"icon\">\n <svg\n class=\"empty-glyph\"\n viewBox=\"${viewBox}\"\n width=\"${FALLBACK_ICON_SIZE}\"\n height=\"${FALLBACK_ICON_SIZE}\"\n aria-hidden=\"true\"\n >\n ${unsafeSVG(andrsrxnInbox.body)}\n </svg>\n </slot>\n </div>\n <div class=${classMap({ 'empty-title': true, 'is-hidden': !showTitle })}>\n <slot @slotchange=${this._syncSlotContent}>${this.title}</slot>\n </div>\n <div class=${classMap({ 'empty-description': true, 'is-hidden': !showDescription })}>\n <slot name=\"description\" @slotchange=${this._syncSlotContent}>${this.description}</slot>\n </div>\n <div class=${classMap({ 'empty-action': true, 'is-hidden': !this._hasActionSlot })}>\n <slot name=\"action\" @slotchange=${this._syncSlotContent}></slot>\n </div>\n </section>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-empty': WebUiEmpty\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,MAAM,yBAAyB;;;;;AAM/B,MAAM,qBAAqB;AAapB,IAAM,aAAN,MAAM,mBAAmB,WAAW;;;EAGmB,KAAA,QAAA;EAEH,KAAA,cAAA;EAExB,KAAA,gBAAA;EACM,KAAA,sBAAA;EACL,KAAA,iBAAA;EAOD,KAAA,yBAAA;GAC/B,KAAK,gBAAgB,KAAK,oBAAoB;GAC9C,KAAK,sBAAsB,KAAK,oBAAoB,aAAa;GACjE,KAAK,iBAAiB,KAAK,oBAAoB,QAAQ;EACzD;;;EAnByB,KAAA,SAAA,CAAC,UAAUA,aAAK,CAAC;;CAU1C,oBAA6B;EAC3B,MAAM,kBAAkB;EACxB,KAAK,iBAAiB;CACxB;CAQA,oBAA4B,UAA4B;EACtD,OAAO,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,MAAK,SAAQ;GACvC,IAAI,gBAAgB,gBAAgB,KAAK,aAAa,MAAM,KAAK,SAAS,YAAY,KAAK,OAAO;GAClG,OAAO,CAAC,YAAY,KAAK,aAAa,KAAK,aAAa,QAAQ,KAAK,aAAa,KAAK,CAAC;EAC1F,CAAC;CACH;CAEA,SAAkB;EAChB,MAAM,YAAY,KAAK,iBAAiB,QAAQ,KAAK,KAAK;EAC1D,MAAM,kBAAkB,KAAK,uBAAuB,QAAQ,KAAK,WAAW;EAG5E,MAAM,QAAqBC;EAC3B,MAAM,UAAU,GAAG,MAAM,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE,GAAG,MAAM,SAAS,uBAAuB,GAC5F,MAAM,UAAU;EAGlB,OAAO,IAAI;;;;;;yBAMU,QAAQ;uBACV,mBAAmB;wBAClB,mBAAmB;;;gBAG3B,UAAUA,uBAAc,IAAI,EAAE;;;;qBAIzB,SAAS;GAAE,eAAe;GAAM,aAAa,CAAC;EAAU,CAAC,EAAE;8BAClD,KAAK,iBAAiB,GAAG,KAAK,MAAM;;qBAE7C,SAAS;GAAE,qBAAqB;GAAM,aAAa,CAAC;EAAgB,CAAC,EAAE;iDAC3C,KAAK,iBAAiB,GAAG,KAAK,YAAY;;qBAEtE,SAAS;GAAE,gBAAgB;GAAM,aAAa,CAAC,KAAK;EAAe,CAAC,EAAE;4CAC/C,KAAK,iBAAiB;;;;CAIhE;AACF;AA/DG,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,WAAA,WAAA,SAAA,KAAA,CAAA;AAExC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,WAAA,WAAA,eAAA,KAAA,CAAA;AAExC,WAAA,CAAA,MAAM,CAAA,GAAA,WAAA,WAAA,iBAAA,KAAA,CAAA;AACN,WAAA,CAAA,MAAM,CAAA,GAAA,WAAA,WAAA,uBAAA,KAAA,CAAA;AACN,WAAA,CAAA,MAAM,CAAA,GAAA,WAAA,WAAA,kBAAA,KAAA,CAAA;AAVR,aAAA,WAAA,CAAA,cAAc,cAAc,CAAA,GAAA,UAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
export { e as default };
|
|
1
|
+
// src/components/empty/style.css?inline
|
|
2
|
+
var style_default = "*,:before,:after{box-sizing:border-box}:host{display:block}.empty{width:100%;min-block-size:var(--wui-empty-min-height,240px);padding:var(--wui-empty-padding,32px 24px);text-align:center;flex-direction:column;align-items:center;display:flex}.empty-icon{inline-size:var(--wui-empty-icon-size,40px);block-size:var(--wui-empty-icon-size,40px);color:var(--wui-empty-icon-color,var(--wui-color-text-secondary,#6a6a6a));flex:none;justify-content:center;align-items:center;display:flex}.empty-glyph{block-size:100%;inline-size:100%;opacity:var(--wui-empty-icon-opacity,.75);display:block}.empty-title,.empty-description,.empty-action{max-inline-size:var(--wui-empty-content-width,480px)}.empty-title{margin-top:var(--wui-empty-title-margin-top,var(--wui-space-3,12px));font-size:var(--wui-empty-title-font-size,16px);font-weight:var(--wui-font-weight-semibold,600);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-empty-title-color,var(--wui-color-text,#1b1b1b));overflow-wrap:anywhere}.empty-description{font-size:var(--wui-empty-description-font-size,14px);line-height:var(--wui-line-height-relaxed,1.6);color:var(--wui-empty-description-color,var(--wui-color-text-secondary,#6a6a6a));overflow-wrap:anywhere;margin-top:6px}.empty-action{margin-top:var(--wui-empty-action-margin-top,var(--wui-space-5,20px))}.is-hidden{display:none}\n";
|
|
3
|
+
export { style_default as default };
|
|
5
4
|
|
|
6
5
|
//# sourceMappingURL=style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/empty/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n\n width: 100%;\n min-block-size: var(--wui-empty-min-height, 240px);\n padding: var(--wui-empty-padding, 32px 24px);\n\n text-align: center;\n}\n\n.empty-icon {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n /*\n * 盒与图形同尺寸:底色退役后隐形内边距只会把图形推离标题(#440)。盒不比图形大,\n * 图形与标题之间的距离就正好是 .empty-title 的 margin-top。\n */\n inline-size: var(--wui-empty-icon-size, 40px);\n block-size: var(--wui-empty-icon-size, 40px);\n\n /*\n * 纯图形,不绘制底面:盒只负责占位与居中,图形直接坐在它背后那张表面上,\n * 因此这里既不画背景也不画阴影,圆角随之无对象可作用。\n *\n * 取实色 secondary,不掺 alpha:线框图形的笔画在转角与端点处本来就互相重叠\n * (填底压在描边上、横线与外轮廓在两端交汇),带 alpha 的颜色会在这些重叠处\n * 二次合成、局部变深,看起来像\"角上笔画发黑\"。淡一档由 .empty-glyph 的\n * group opacity 负责——那是在整颗图形合成之后一次性施加的,重叠处不起变化。\n */\n color: var(--wui-empty-icon-color, var(--wui-color-text-secondary, #6a6a6a));\n}\n\n/*\n * 默认图形填满盒:`width` / `height` 属性只兜首帧,尺寸的单一来源是 --wui-empty-icon-size。\n * 图形资产用 currentColor 描边与填充,颜色因此跟着 .empty-icon 的 color 走。\n *\n * 0.75 把整颗默认色压到 secondary 与 tertiary 之间(浅色合成 #8f8f8f ≈ 3.22:1,\n * 深色合成 #828282 ≈ 3.98:1,两档都守住非文本图形的 3:1),比整颗 secondary 轻,\n * 又不至于像 tertiary 那样在浅色 page 上只有 2.19:1。\n *\n * 关键在这是 group opacity:整颗 SVG 先按不透明合成成一层,再统一按 0.75 落到背景上。\n * 若改用带 alpha 的颜色,每条绘制指令各自带 0.75,笔画重叠处会叠到 0.94,交角明显发黑。\n * 只作用于默认图形,`icon` 插槽里的内容由调用方自己控制颜色与深浅。\n */\n.empty-glyph {\n display: block;\n inline-size: 100%;\n block-size: 100%;\n opacity: var(--wui-empty-icon-opacity, 0.75);\n}\n\n.empty-title,\n.empty-description,\n.empty-action {\n max-inline-size: var(--wui-empty-content-width, 480px);\n}\n\n.empty-title {\n /*\n * 图形自身在 40px 见方的框里还带一圈线条留白,视觉间隙因此比数值看着更大,\n * 收到 space-3(12px)才和标题读成一组。\n */\n margin-top: var(--wui-empty-title-margin-top, var(--wui-space-3, 12px));\n\n font-size: var(--wui-empty-title-font-size, 16px);\n font-weight: var(--wui-font-weight-semibold, 600);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-empty-title-color, var(--wui-color-text, #1b1b1b));\n overflow-wrap: anywhere;\n}\n\n.empty-description {\n margin-top: 6px;\n\n font-size: var(--wui-empty-description-font-size, 14px);\n line-height: var(--wui-line-height-relaxed, 1.6);\n color: var(--wui-empty-description-color, var(--wui-color-text-secondary, #6a6a6a));\n overflow-wrap: anywhere;\n}\n\n.empty-action {\n margin-top: var(--wui-empty-action-margin-top, var(--wui-space-5, 20px));\n}\n\n.is-hidden {\n display: none;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/empty/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n\n width: 100%;\n min-block-size: var(--wui-empty-min-height, 240px);\n padding: var(--wui-empty-padding, 32px 24px);\n\n text-align: center;\n}\n\n.empty-icon {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n /*\n * 盒与图形同尺寸:底色退役后隐形内边距只会把图形推离标题(#440)。盒不比图形大,\n * 图形与标题之间的距离就正好是 .empty-title 的 margin-top。\n */\n inline-size: var(--wui-empty-icon-size, 40px);\n block-size: var(--wui-empty-icon-size, 40px);\n\n /*\n * 纯图形,不绘制底面:盒只负责占位与居中,图形直接坐在它背后那张表面上,\n * 因此这里既不画背景也不画阴影,圆角随之无对象可作用。\n *\n * 取实色 secondary,不掺 alpha:线框图形的笔画在转角与端点处本来就互相重叠\n * (填底压在描边上、横线与外轮廓在两端交汇),带 alpha 的颜色会在这些重叠处\n * 二次合成、局部变深,看起来像\"角上笔画发黑\"。淡一档由 .empty-glyph 的\n * group opacity 负责——那是在整颗图形合成之后一次性施加的,重叠处不起变化。\n */\n color: var(--wui-empty-icon-color, var(--wui-color-text-secondary, #6a6a6a));\n}\n\n/*\n * 默认图形填满盒:`width` / `height` 属性只兜首帧,尺寸的单一来源是 --wui-empty-icon-size。\n * 图形资产用 currentColor 描边与填充,颜色因此跟着 .empty-icon 的 color 走。\n *\n * 0.75 把整颗默认色压到 secondary 与 tertiary 之间(浅色合成 #8f8f8f ≈ 3.22:1,\n * 深色合成 #828282 ≈ 3.98:1,两档都守住非文本图形的 3:1),比整颗 secondary 轻,\n * 又不至于像 tertiary 那样在浅色 page 上只有 2.19:1。\n *\n * 关键在这是 group opacity:整颗 SVG 先按不透明合成成一层,再统一按 0.75 落到背景上。\n * 若改用带 alpha 的颜色,每条绘制指令各自带 0.75,笔画重叠处会叠到 0.94,交角明显发黑。\n * 只作用于默认图形,`icon` 插槽里的内容由调用方自己控制颜色与深浅。\n */\n.empty-glyph {\n display: block;\n inline-size: 100%;\n block-size: 100%;\n opacity: var(--wui-empty-icon-opacity, 0.75);\n}\n\n.empty-title,\n.empty-description,\n.empty-action {\n max-inline-size: var(--wui-empty-content-width, 480px);\n}\n\n.empty-title {\n /*\n * 图形自身在 40px 见方的框里还带一圈线条留白,视觉间隙因此比数值看着更大,\n * 收到 space-3(12px)才和标题读成一组。\n */\n margin-top: var(--wui-empty-title-margin-top, var(--wui-space-3, 12px));\n\n font-size: var(--wui-empty-title-font-size, 16px);\n font-weight: var(--wui-font-weight-semibold, 600);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-empty-title-color, var(--wui-color-text, #1b1b1b));\n overflow-wrap: anywhere;\n}\n\n.empty-description {\n margin-top: 6px;\n\n font-size: var(--wui-empty-description-font-size, 14px);\n line-height: var(--wui-line-height-relaxed, 1.6);\n color: var(--wui-empty-description-color, var(--wui-color-text-secondary, #6a6a6a));\n overflow-wrap: anywhere;\n}\n\n.empty-action {\n margin-top: var(--wui-empty-action-margin-top, var(--wui-space-5, 20px));\n}\n\n.is-hidden {\n display: none;\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { LitElement, nothing } from "lit";
|
|
2
|
+
import { IconifyIcon } from "@iconify/types";
|
|
3
3
|
export declare class WebUiIcon extends LitElement {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
static styles: import("lit").CSSResult;
|
|
5
|
+
icon?: IconifyIcon;
|
|
6
|
+
spin: boolean;
|
|
7
|
+
size: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
render(): import("lit").TemplateResult<1> | typeof nothing;
|
|
10
10
|
}
|
|
11
11
|
declare global {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
interface HTMLElementTagNameMap {
|
|
13
|
+
'web-ui-icon': WebUiIcon;
|
|
14
|
+
}
|
|
15
15
|
}
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/icon/index.ts"],"mappings":";;qBAgBa,kBAAkB;SACb,sBAAM;EAEU,OAAO;EACK;EACD;EACA;EAElC,wBAAM,2BAAA;;QAqBT;YACI;IACR,eAAe"}
|
|
@@ -1,45 +1,52 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { LitElement
|
|
4
|
-
import { customElement
|
|
5
|
-
import { classMap
|
|
6
|
-
import { unsafeSVG
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import style_default from "./style.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
3
|
+
import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
4
|
+
import { customElement, property } from "lit/decorators.js";
|
|
5
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
6
|
+
import { unsafeSVG } from "lit/directives/unsafe-svg.js";
|
|
7
|
+
// src/components/icon/index.ts
|
|
8
|
+
const ICONIFY_DEFAULT_CANVAS = 16;
|
|
9
|
+
let WebUiIcon = class WebUiIcon extends LitElement {
|
|
10
|
+
constructor(..._args) {
|
|
11
|
+
super(..._args);
|
|
12
|
+
this.spin = false;
|
|
13
|
+
this.size = 18;
|
|
11
14
|
}
|
|
12
15
|
static {
|
|
13
|
-
this.styles =
|
|
16
|
+
this.styles = unsafeCSS(style_default);
|
|
14
17
|
}
|
|
15
18
|
render() {
|
|
16
|
-
if (!this.icon) return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
if (!this.icon) return nothing;
|
|
20
|
+
const svgStyle = this.color ? `color: ${this.color}` : "";
|
|
21
|
+
const viewBox = `${this.icon.left ?? 0} ${this.icon.top ?? 0} ${this.icon.width ?? ICONIFY_DEFAULT_CANVAS} ${this.icon.height ?? ICONIFY_DEFAULT_CANVAS}`;
|
|
22
|
+
return html`
|
|
19
23
|
<svg
|
|
20
|
-
class=${
|
|
21
|
-
style=${
|
|
22
|
-
viewBox="${
|
|
24
|
+
class=${classMap({ spin: this.spin })}
|
|
25
|
+
style=${svgStyle}
|
|
26
|
+
viewBox="${viewBox}"
|
|
23
27
|
width="${this.size}"
|
|
24
28
|
height="${this.size}"
|
|
25
29
|
aria-hidden="true"
|
|
26
30
|
>
|
|
27
|
-
${
|
|
31
|
+
${unsafeSVG(this.icon.body)}
|
|
28
32
|
</svg>
|
|
29
33
|
`;
|
|
30
34
|
}
|
|
31
35
|
};
|
|
32
|
-
|
|
36
|
+
__decorate([property({ attribute: false })], WebUiIcon.prototype, "icon", void 0);
|
|
37
|
+
__decorate([property({
|
|
33
38
|
type: Boolean,
|
|
34
|
-
reflect:
|
|
35
|
-
})],
|
|
39
|
+
reflect: true
|
|
40
|
+
})], WebUiIcon.prototype, "spin", void 0);
|
|
41
|
+
__decorate([property({
|
|
36
42
|
type: Number,
|
|
37
|
-
reflect:
|
|
38
|
-
})],
|
|
43
|
+
reflect: true
|
|
44
|
+
})], WebUiIcon.prototype, "size", void 0);
|
|
45
|
+
__decorate([property({
|
|
39
46
|
type: String,
|
|
40
|
-
reflect:
|
|
41
|
-
})],
|
|
42
|
-
|
|
43
|
-
export {
|
|
47
|
+
reflect: true
|
|
48
|
+
})], WebUiIcon.prototype, "color", void 0);
|
|
49
|
+
WebUiIcon = __decorate([customElement("web-ui-icon")], WebUiIcon);
|
|
50
|
+
export { WebUiIcon };
|
|
44
51
|
|
|
45
52
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/icon/index.ts"],"sourcesContent":["import type { IconifyIcon } from '@iconify/types'\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js'\n\nimport style from './style.css?inline'\n\n/*\n * Iconify 规范里 width/height 缺省即 16(见 @iconify/types README),这里必须跟规范一致:\n * 猜成别的值不会报错,只会把图形按错误比例缩放并偏到画布一角。生成资产已自带尺寸,\n * 这条兜底服务的是直接喂进来的原始 IconifyIcon 对象。\n */\nconst ICONIFY_DEFAULT_CANVAS = 16\n\n@customElement('web-ui-icon')\nexport class WebUiIcon extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ attribute: false }) icon?: IconifyIcon\n @property({ type: Boolean, reflect: true }) spin = false\n @property({ type: Number, reflect: true }) size: number = 18\n @property({ type: String, reflect: true }) color?: string\n\n override render() {\n if (!this.icon) return nothing\n\n const svgStyle = this.color ? `color: ${this.color}` : ''\n const viewBox = `${this.icon.left ?? 0} ${this.icon.top ?? 0} ${this.icon.width ?? ICONIFY_DEFAULT_CANVAS} ${this.icon.height ?? ICONIFY_DEFAULT_CANVAS}`\n\n return html`\n <svg\n class=${classMap({ spin: this.spin })}\n style=${svgStyle}\n viewBox=\"${viewBox}\"\n width=\"${this.size}\"\n height=\"${this.size}\"\n aria-hidden=\"true\"\n >\n ${unsafeSVG(this.icon.body)}\n </svg>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-icon': WebUiIcon\n }\n}\n"],"mappings":";;;;;;;AAaA,
|
|
1
|
+
{"version":3,"file":"index.js","names":["style"],"sources":["../../../src/components/icon/index.ts"],"sourcesContent":["import type { IconifyIcon } from '@iconify/types'\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js'\n\nimport style from './style.css?inline'\n\n/*\n * Iconify 规范里 width/height 缺省即 16(见 @iconify/types README),这里必须跟规范一致:\n * 猜成别的值不会报错,只会把图形按错误比例缩放并偏到画布一角。生成资产已自带尺寸,\n * 这条兜底服务的是直接喂进来的原始 IconifyIcon 对象。\n */\nconst ICONIFY_DEFAULT_CANVAS = 16\n\n@customElement('web-ui-icon')\nexport class WebUiIcon extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ attribute: false }) icon?: IconifyIcon\n @property({ type: Boolean, reflect: true }) spin = false\n @property({ type: Number, reflect: true }) size: number = 18\n @property({ type: String, reflect: true }) color?: string\n\n override render() {\n if (!this.icon) return nothing\n\n const svgStyle = this.color ? `color: ${this.color}` : ''\n const viewBox = `${this.icon.left ?? 0} ${this.icon.top ?? 0} ${this.icon.width ?? ICONIFY_DEFAULT_CANVAS} ${this.icon.height ?? ICONIFY_DEFAULT_CANVAS}`\n\n return html`\n <svg\n class=${classMap({ spin: this.spin })}\n style=${svgStyle}\n viewBox=\"${viewBox}\"\n width=\"${this.size}\"\n height=\"${this.size}\"\n aria-hidden=\"true\"\n >\n ${unsafeSVG(this.icon.body)}\n </svg>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-icon': WebUiIcon\n }\n}\n"],"mappings":";;;;;;;AAaA,MAAM,yBAAyB;AAGxB,IAAM,YAAN,MAAM,kBAAkB,WAAW;;;EAIW,KAAA,OAAA;EACO,KAAA,OAAA;;;EAJjC,KAAA,SAAA,UAAUA,aAAK;;CAOxC,SAAkB;EAChB,IAAI,CAAC,KAAK,MAAM,OAAO;EAEvB,MAAM,WAAW,KAAK,QAAQ,UAAU,KAAK,UAAU;EACvD,MAAM,UAAU,GAAG,KAAK,KAAK,QAAQ,EAAE,GAAG,KAAK,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,SAAS,uBAAuB,GAAG,KAAK,KAAK,UAAU;EAEjI,OAAO,IAAI;;gBAEC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC,EAAE;gBAC9B,SAAS;mBACN,QAAQ;iBACV,KAAK,KAAK;kBACT,KAAK,KAAK;;;UAGlB,UAAU,KAAK,KAAK,IAAI,EAAE;;;CAGlC;AACF;AAxBG,WAAA,CAAA,SAAS,EAAE,WAAW,MAAM,CAAC,CAAA,GAAA,UAAA,WAAA,QAAA,KAAA,CAAA;AAC7B,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,UAAA,WAAA,QAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,UAAA,WAAA,QAAA,KAAA,CAAA;AACxC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,UAAA,WAAA,SAAA,KAAA,CAAA;AAP1C,YAAA,WAAA,CAAA,cAAc,aAAa,CAAA,GAAA,SAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
export { e as default };
|
|
1
|
+
// src/components/icon/style.css?inline
|
|
2
|
+
var style_default = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-flex}svg{color:var(--wui-icon-color,inherit);display:block}svg.spin{animation:wui-icon-spin var(--wui-duration-spin,.6s) linear infinite}@keyframes wui-icon-spin{to{transform:rotate(360deg)}}\n";
|
|
3
|
+
export { style_default as default };
|
|
5
4
|
|
|
6
5
|
//# sourceMappingURL=style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/icon/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-flex;\n}\n\nsvg {\n display: block;\n color: var(--wui-icon-color, inherit);\n}\n\n/* 周期走主题 token:组件级 @media 块看不到 motion 属性,只有 token 能同时响应\n 显式 motion=\"reduced\" 与系统 prefers-reduced-motion。 */\nsvg.spin {\n animation: wui-icon-spin var(--wui-duration-spin, 600ms) linear infinite;\n}\n\n@keyframes wui-icon-spin {\n to {\n transform: rotate(360deg);\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/icon/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-flex;\n}\n\nsvg {\n display: block;\n color: var(--wui-icon-color, inherit);\n}\n\n/* 周期走主题 token:组件级 @media 块看不到 motion 属性,只有 token 能同时响应\n 显式 motion=\"reduced\" 与系统 prefers-reduced-motion。 */\nsvg.spin {\n animation: wui-icon-spin var(--wui-duration-spin, 600ms) linear infinite;\n}\n\n@keyframes wui-icon-spin {\n to {\n transform: rotate(360deg);\n }\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
|