@jackuait/blok 0.6.0 → 0.7.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -4
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-BAh1rvUC.mjs → blok-D9Rs29Wo.mjs} +1928 -1793
- package/dist/chunks/{inline-tool-convert-DduRc0fF.mjs → constants-DmNIR3I8.mjs} +596 -475
- package/dist/chunks/{i18next-loader-CHtGO6IK.mjs → i18next-loader-C2-jYpLi.mjs} +1 -1
- package/dist/chunks/index-D7V1g7Oq.mjs +130 -0
- package/dist/chunks/{messages-D2NOpHn9.mjs → messages-0Pxnqd4N.mjs} +7 -0
- package/dist/chunks/{messages-GSByFygY.mjs → messages-0ZXYUq7S.mjs} +7 -0
- package/dist/{messages-BUl_Rcnj.mjs → chunks/messages-2OD2uUDS.mjs} +9 -2
- package/dist/{messages-CgTq3QhU.mjs → chunks/messages-7cEMfYzh.mjs} +7 -0
- package/dist/{messages-DlJbPF2T.mjs → chunks/messages-8mwfda1Q.mjs} +7 -0
- package/dist/{messages-D9ndgBnU.mjs → chunks/messages-B-FqWsBM.mjs} +7 -0
- package/dist/{messages-B217znr-.mjs → chunks/messages-B1jzqWiQ.mjs} +7 -0
- package/dist/{messages-BcpCubnC.mjs → chunks/messages-B5wk4Ezz.mjs} +7 -0
- package/dist/chunks/{messages-DRXWF0PV.mjs → messages-BAZ5Ld8x.mjs} +7 -0
- package/dist/{messages-CRJ_mchV.mjs → chunks/messages-BBhGp198.mjs} +7 -0
- package/dist/chunks/{messages-yHcs38yI.mjs → messages-BC9IjIb7.mjs} +7 -0
- package/dist/chunks/{messages-Cr94GzbX.mjs → messages-BFEmpeV-.mjs} +7 -0
- package/dist/chunks/{messages-ucTVgS5G.mjs → messages-BGqzTZy0.mjs} +7 -0
- package/dist/{messages-begYOTgC.mjs → chunks/messages-BICs1abK.mjs} +7 -0
- package/dist/chunks/{messages-DVQvl8Qj.mjs → messages-BJX6rOnd.mjs} +7 -0
- package/dist/chunks/{messages-Chb7k3Rg.mjs → messages-BL2bXRhN.mjs} +7 -0
- package/dist/{messages-Phkd7XmE.mjs → chunks/messages-BMs5qdlH.mjs} +7 -0
- package/dist/chunks/{messages-Cjjo7yHR.mjs → messages-BRsjUNwB.mjs} +7 -0
- package/dist/chunks/{messages-D4qqwVgQ.mjs → messages-BSqV8OUR.mjs} +7 -0
- package/dist/chunks/{messages-DviiFSv2.mjs → messages-BTqu3DfG.mjs} +7 -0
- package/dist/chunks/{messages-0AbcLMLm.mjs → messages-BXnDEsur.mjs} +7 -0
- package/dist/{messages-CmR9ftc_.mjs → chunks/messages-BYcre4-6.mjs} +7 -0
- package/dist/{messages-wmi-iFkH.mjs → chunks/messages-BZ9LRJf-.mjs} +7 -0
- package/dist/chunks/{messages-D00x4S8o.mjs → messages-BgypBy7y.mjs} +7 -0
- package/dist/{messages-96kNZDll.mjs → chunks/messages-BsuGf70G.mjs} +7 -0
- package/dist/chunks/{messages-v3GipbFl.mjs → messages-BwaoF4lQ.mjs} +7 -0
- package/dist/{messages-DDTQgImT.mjs → chunks/messages-C1l8_7-y.mjs} +7 -0
- package/dist/{messages-B1FZ8lxU.mjs → chunks/messages-C5NA_r9v.mjs} +7 -0
- package/dist/{messages-Cs8zmZ3L.mjs → chunks/messages-C6zgZ5pA.mjs} +7 -0
- package/dist/chunks/{messages-ZjUAIWb1.mjs → messages-CAo5ghFI.mjs} +7 -0
- package/dist/{messages-D5S1Dnpm.mjs → chunks/messages-CH9qlJ9I.mjs} +7 -0
- package/dist/{messages-D7u2bmP2.mjs → chunks/messages-CI0HqAeS.mjs} +7 -0
- package/dist/{messages-DH_jBeED.mjs → chunks/messages-CJJtms9k.mjs} +7 -0
- package/dist/{messages-CDBLbUOQ.mjs → chunks/messages-CM2hJqk6.mjs} +7 -0
- package/dist/chunks/{messages-8IPXkrDl.mjs → messages-CRMiDPIQ.mjs} +7 -0
- package/dist/chunks/{messages-Dzzn6XoD.mjs → messages-CWsZuBj1.mjs} +7 -0
- package/dist/chunks/{messages-CW4c4cRk.mjs → messages-C_gLHo6A.mjs} +7 -0
- package/dist/{messages-CH4hrauY.mjs → chunks/messages-Cbu-NUDn.mjs} +7 -0
- package/dist/{messages-RonBBCnh.mjs → chunks/messages-Cjb_MCeh.mjs} +7 -0
- package/dist/chunks/{messages-BJ6zrz2j.mjs → messages-ClXYO9Wn.mjs} +7 -0
- package/dist/chunks/{messages-CrCYPCk3.mjs → messages-CsH20vhP.mjs} +7 -0
- package/dist/{messages-CzK0LEhb.mjs → chunks/messages-CsjAGhzA.mjs} +7 -0
- package/dist/chunks/{messages-BZlmVRwn.mjs → messages-Cx7VKFOE.mjs} +7 -0
- package/dist/chunks/{messages-0E0AkrNu.mjs → messages-D3JeBwxo.mjs} +7 -0
- package/dist/chunks/{messages-D85FqxgY.mjs → messages-D541fieJ.mjs} +7 -0
- package/dist/{messages-4v4MuVEc.mjs → chunks/messages-D7XPdglc.mjs} +7 -0
- package/dist/{messages-BC8IN4Bf.mjs → chunks/messages-DBhylfvt.mjs} +7 -0
- package/dist/chunks/{messages-B8WNljW3.mjs → messages-DCA120lW.mjs} +7 -0
- package/dist/chunks/{messages-Cr49Nt3U.mjs → messages-DCf_xZMN.mjs} +7 -0
- package/dist/chunks/{messages-VDriF5Qy.mjs → messages-DDwXKCpe.mjs} +7 -0
- package/dist/{messages-b1EdvUm0.mjs → chunks/messages-DNKDlxcy.mjs} +7 -0
- package/dist/{messages-L_kl2Qvh.mjs → chunks/messages-DPvEjrGK.mjs} +7 -0
- package/dist/chunks/{messages-62v-CLC-.mjs → messages-DQ-AkNxA.mjs} +7 -0
- package/dist/chunks/{messages-DdK-nFGm.mjs → messages-DVuvkNap.mjs} +7 -0
- package/dist/{messages-DnVlmiNT.mjs → chunks/messages-DaglyqUT.mjs} +7 -0
- package/dist/{messages-Bm-E4iRC.mjs → chunks/messages-Di0bAfwA.mjs} +7 -0
- package/dist/{messages-D1mn7Zd5.mjs → chunks/messages-DuLct0Yr.mjs} +7 -0
- package/dist/{messages-8DeO60Oo.mjs → chunks/messages-DzEYYhZh.mjs} +7 -0
- package/dist/chunks/{messages-CfiyT2Wi.mjs → messages-DznNGAB2.mjs} +7 -0
- package/dist/chunks/{messages-DXktiao_.mjs → messages-DzoIzyu8.mjs} +7 -0
- package/dist/{messages-C_4otP7U.mjs → chunks/messages-QYOGmket.mjs} +7 -0
- package/dist/chunks/{messages-nefz1S71.mjs → messages-cEjGDAgI.mjs} +7 -0
- package/dist/chunks/{messages-jrncnb-H.mjs → messages-ddhvrdpE.mjs} +7 -0
- package/dist/chunks/{messages-DzqM3Fel.mjs → messages-mwfNK5nZ.mjs} +7 -0
- package/dist/chunks/{messages-Cl6ayUaq.mjs → messages-nG_vNDte.mjs} +7 -0
- package/dist/{messages-C4jL-90N.mjs → chunks/messages-tDq3Owh7.mjs} +7 -0
- package/dist/{messages-BI43k_BD.mjs → chunks/messages-x6VJVZKx.mjs} +7 -0
- package/dist/full.mjs +30 -27
- package/dist/locales.mjs +87 -80
- package/dist/{messages-D2NOpHn9.mjs → messages-0Pxnqd4N.mjs} +7 -0
- package/dist/{messages-GSByFygY.mjs → messages-0ZXYUq7S.mjs} +7 -0
- package/dist/{chunks/messages-BUl_Rcnj.mjs → messages-2OD2uUDS.mjs} +9 -2
- package/dist/{chunks/messages-CgTq3QhU.mjs → messages-7cEMfYzh.mjs} +7 -0
- package/dist/{chunks/messages-DlJbPF2T.mjs → messages-8mwfda1Q.mjs} +7 -0
- package/dist/{chunks/messages-D9ndgBnU.mjs → messages-B-FqWsBM.mjs} +7 -0
- package/dist/{chunks/messages-B217znr-.mjs → messages-B1jzqWiQ.mjs} +7 -0
- package/dist/{chunks/messages-BcpCubnC.mjs → messages-B5wk4Ezz.mjs} +7 -0
- package/dist/{messages-DRXWF0PV.mjs → messages-BAZ5Ld8x.mjs} +7 -0
- package/dist/{chunks/messages-CRJ_mchV.mjs → messages-BBhGp198.mjs} +7 -0
- package/dist/{messages-yHcs38yI.mjs → messages-BC9IjIb7.mjs} +7 -0
- package/dist/{messages-Cr94GzbX.mjs → messages-BFEmpeV-.mjs} +7 -0
- package/dist/{messages-ucTVgS5G.mjs → messages-BGqzTZy0.mjs} +7 -0
- package/dist/{chunks/messages-begYOTgC.mjs → messages-BICs1abK.mjs} +7 -0
- package/dist/{messages-DVQvl8Qj.mjs → messages-BJX6rOnd.mjs} +7 -0
- package/dist/{messages-Chb7k3Rg.mjs → messages-BL2bXRhN.mjs} +7 -0
- package/dist/{chunks/messages-Phkd7XmE.mjs → messages-BMs5qdlH.mjs} +7 -0
- package/dist/{messages-Cjjo7yHR.mjs → messages-BRsjUNwB.mjs} +7 -0
- package/dist/{messages-D4qqwVgQ.mjs → messages-BSqV8OUR.mjs} +7 -0
- package/dist/{messages-DviiFSv2.mjs → messages-BTqu3DfG.mjs} +7 -0
- package/dist/{messages-0AbcLMLm.mjs → messages-BXnDEsur.mjs} +7 -0
- package/dist/{chunks/messages-CmR9ftc_.mjs → messages-BYcre4-6.mjs} +7 -0
- package/dist/{chunks/messages-wmi-iFkH.mjs → messages-BZ9LRJf-.mjs} +7 -0
- package/dist/{messages-D00x4S8o.mjs → messages-BgypBy7y.mjs} +7 -0
- package/dist/{chunks/messages-96kNZDll.mjs → messages-BsuGf70G.mjs} +7 -0
- package/dist/{messages-v3GipbFl.mjs → messages-BwaoF4lQ.mjs} +7 -0
- package/dist/{chunks/messages-DDTQgImT.mjs → messages-C1l8_7-y.mjs} +7 -0
- package/dist/{chunks/messages-B1FZ8lxU.mjs → messages-C5NA_r9v.mjs} +7 -0
- package/dist/{chunks/messages-Cs8zmZ3L.mjs → messages-C6zgZ5pA.mjs} +7 -0
- package/dist/{messages-ZjUAIWb1.mjs → messages-CAo5ghFI.mjs} +7 -0
- package/dist/{chunks/messages-D5S1Dnpm.mjs → messages-CH9qlJ9I.mjs} +7 -0
- package/dist/{chunks/messages-D7u2bmP2.mjs → messages-CI0HqAeS.mjs} +7 -0
- package/dist/{chunks/messages-DH_jBeED.mjs → messages-CJJtms9k.mjs} +7 -0
- package/dist/{chunks/messages-CDBLbUOQ.mjs → messages-CM2hJqk6.mjs} +7 -0
- package/dist/{messages-8IPXkrDl.mjs → messages-CRMiDPIQ.mjs} +7 -0
- package/dist/{messages-Dzzn6XoD.mjs → messages-CWsZuBj1.mjs} +7 -0
- package/dist/{messages-CW4c4cRk.mjs → messages-C_gLHo6A.mjs} +7 -0
- package/dist/{chunks/messages-CH4hrauY.mjs → messages-Cbu-NUDn.mjs} +7 -0
- package/dist/{chunks/messages-RonBBCnh.mjs → messages-Cjb_MCeh.mjs} +7 -0
- package/dist/{messages-BJ6zrz2j.mjs → messages-ClXYO9Wn.mjs} +7 -0
- package/dist/{messages-CrCYPCk3.mjs → messages-CsH20vhP.mjs} +7 -0
- package/dist/{chunks/messages-CzK0LEhb.mjs → messages-CsjAGhzA.mjs} +7 -0
- package/dist/{messages-BZlmVRwn.mjs → messages-Cx7VKFOE.mjs} +7 -0
- package/dist/{messages-0E0AkrNu.mjs → messages-D3JeBwxo.mjs} +7 -0
- package/dist/{messages-D85FqxgY.mjs → messages-D541fieJ.mjs} +7 -0
- package/dist/{chunks/messages-4v4MuVEc.mjs → messages-D7XPdglc.mjs} +7 -0
- package/dist/{chunks/messages-BC8IN4Bf.mjs → messages-DBhylfvt.mjs} +7 -0
- package/dist/{messages-B8WNljW3.mjs → messages-DCA120lW.mjs} +7 -0
- package/dist/{messages-Cr49Nt3U.mjs → messages-DCf_xZMN.mjs} +7 -0
- package/dist/{messages-VDriF5Qy.mjs → messages-DDwXKCpe.mjs} +7 -0
- package/dist/{chunks/messages-b1EdvUm0.mjs → messages-DNKDlxcy.mjs} +7 -0
- package/dist/{chunks/messages-L_kl2Qvh.mjs → messages-DPvEjrGK.mjs} +7 -0
- package/dist/{messages-62v-CLC-.mjs → messages-DQ-AkNxA.mjs} +7 -0
- package/dist/{messages-DdK-nFGm.mjs → messages-DVuvkNap.mjs} +7 -0
- package/dist/{chunks/messages-DnVlmiNT.mjs → messages-DaglyqUT.mjs} +7 -0
- package/dist/{chunks/messages-Bm-E4iRC.mjs → messages-Di0bAfwA.mjs} +7 -0
- package/dist/{chunks/messages-D1mn7Zd5.mjs → messages-DuLct0Yr.mjs} +7 -0
- package/dist/{chunks/messages-8DeO60Oo.mjs → messages-DzEYYhZh.mjs} +7 -0
- package/dist/{messages-CfiyT2Wi.mjs → messages-DznNGAB2.mjs} +7 -0
- package/dist/{messages-DXktiao_.mjs → messages-DzoIzyu8.mjs} +7 -0
- package/dist/{chunks/messages-C_4otP7U.mjs → messages-QYOGmket.mjs} +7 -0
- package/dist/{messages-nefz1S71.mjs → messages-cEjGDAgI.mjs} +7 -0
- package/dist/{messages-jrncnb-H.mjs → messages-ddhvrdpE.mjs} +7 -0
- package/dist/{messages-DzqM3Fel.mjs → messages-mwfNK5nZ.mjs} +7 -0
- package/dist/{messages-Cl6ayUaq.mjs → messages-nG_vNDte.mjs} +7 -0
- package/dist/{chunks/messages-C4jL-90N.mjs → messages-tDq3Owh7.mjs} +7 -0
- package/dist/{chunks/messages-BI43k_BD.mjs → messages-x6VJVZKx.mjs} +7 -0
- package/dist/tools.mjs +1233 -801
- package/package.json +1 -1
- package/src/components/constants/data-attributes.ts +7 -0
- package/src/components/i18n/locales/am/messages.json +7 -0
- package/src/components/i18n/locales/ar/messages.json +7 -0
- package/src/components/i18n/locales/az/messages.json +7 -0
- package/src/components/i18n/locales/bg/messages.json +7 -0
- package/src/components/i18n/locales/bn/messages.json +7 -0
- package/src/components/i18n/locales/bs/messages.json +7 -0
- package/src/components/i18n/locales/cs/messages.json +7 -0
- package/src/components/i18n/locales/da/messages.json +7 -0
- package/src/components/i18n/locales/de/messages.json +7 -0
- package/src/components/i18n/locales/dv/messages.json +7 -0
- package/src/components/i18n/locales/el/messages.json +7 -0
- package/src/components/i18n/locales/en/messages.json +7 -0
- package/src/components/i18n/locales/es/messages.json +7 -0
- package/src/components/i18n/locales/et/messages.json +7 -0
- package/src/components/i18n/locales/fa/messages.json +7 -0
- package/src/components/i18n/locales/fi/messages.json +7 -0
- package/src/components/i18n/locales/fil/messages.json +7 -0
- package/src/components/i18n/locales/fr/messages.json +7 -0
- package/src/components/i18n/locales/gu/messages.json +7 -0
- package/src/components/i18n/locales/he/messages.json +7 -0
- package/src/components/i18n/locales/hi/messages.json +7 -0
- package/src/components/i18n/locales/hr/messages.json +7 -0
- package/src/components/i18n/locales/hu/messages.json +7 -0
- package/src/components/i18n/locales/hy/messages.json +7 -0
- package/src/components/i18n/locales/id/messages.json +7 -0
- package/src/components/i18n/locales/it/messages.json +7 -0
- package/src/components/i18n/locales/ja/messages.json +7 -0
- package/src/components/i18n/locales/ka/messages.json +7 -0
- package/src/components/i18n/locales/km/messages.json +7 -0
- package/src/components/i18n/locales/kn/messages.json +7 -0
- package/src/components/i18n/locales/ko/messages.json +7 -0
- package/src/components/i18n/locales/ku/messages.json +7 -0
- package/src/components/i18n/locales/lo/messages.json +7 -0
- package/src/components/i18n/locales/lt/messages.json +7 -0
- package/src/components/i18n/locales/lv/messages.json +7 -0
- package/src/components/i18n/locales/mk/messages.json +7 -0
- package/src/components/i18n/locales/ml/messages.json +7 -0
- package/src/components/i18n/locales/mn/messages.json +7 -0
- package/src/components/i18n/locales/mr/messages.json +7 -0
- package/src/components/i18n/locales/ms/messages.json +7 -0
- package/src/components/i18n/locales/my/messages.json +7 -0
- package/src/components/i18n/locales/ne/messages.json +7 -0
- package/src/components/i18n/locales/nl/messages.json +7 -0
- package/src/components/i18n/locales/no/messages.json +7 -0
- package/src/components/i18n/locales/pa/messages.json +7 -0
- package/src/components/i18n/locales/pl/messages.json +7 -0
- package/src/components/i18n/locales/ps/messages.json +7 -0
- package/src/components/i18n/locales/pt/messages.json +7 -0
- package/src/components/i18n/locales/ro/messages.json +7 -0
- package/src/components/i18n/locales/ru/messages.json +7 -0
- package/src/components/i18n/locales/sd/messages.json +7 -0
- package/src/components/i18n/locales/si/messages.json +7 -0
- package/src/components/i18n/locales/sk/messages.json +7 -0
- package/src/components/i18n/locales/sl/messages.json +7 -0
- package/src/components/i18n/locales/sq/messages.json +7 -0
- package/src/components/i18n/locales/sr/messages.json +7 -0
- package/src/components/i18n/locales/sv/messages.json +7 -0
- package/src/components/i18n/locales/sw/messages.json +7 -0
- package/src/components/i18n/locales/ta/messages.json +7 -0
- package/src/components/i18n/locales/te/messages.json +7 -0
- package/src/components/i18n/locales/th/messages.json +7 -0
- package/src/components/i18n/locales/tr/messages.json +7 -0
- package/src/components/i18n/locales/ug/messages.json +7 -0
- package/src/components/i18n/locales/uk/messages.json +7 -0
- package/src/components/i18n/locales/ur/messages.json +7 -0
- package/src/components/i18n/locales/vi/messages.json +7 -0
- package/src/components/i18n/locales/yi/messages.json +7 -0
- package/src/components/i18n/locales/zh/messages.json +7 -0
- package/src/components/icons/index.ts +44 -7
- package/src/components/modules/blockEvents/composers/keyboardNavigation.ts +44 -2
- package/src/components/modules/blockEvents/composers/markdownShortcuts.ts +54 -2
- package/src/components/modules/blockEvents/constants.ts +12 -0
- package/src/components/modules/blockEvents/index.ts +1 -3
- package/src/components/modules/blockManager/blockManager.ts +16 -0
- package/src/components/modules/blockManager/operations.ts +106 -9
- package/src/components/modules/blockSelection.ts +2 -0
- package/src/components/modules/caret.ts +49 -4
- package/src/components/modules/drag/DragController.ts +34 -2
- package/src/components/modules/paste/handlers/blok-data-handler.ts +50 -3
- package/src/components/modules/toolbar/index.ts +11 -16
- package/src/components/modules/ui.ts +12 -0
- package/src/components/ui/toolbox.ts +26 -2
- package/src/components/utils/notifier/draw.ts +116 -14
- package/src/components/utils/notifier/index.ts +31 -4
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +2 -2
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +7 -7
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +2 -2
- package/src/components/utils/popover/components/search-input/search-input.const.ts +1 -1
- package/src/components/utils/popover/popover-abstract.ts +5 -2
- package/src/components/utils/popover/popover-desktop.ts +39 -2
- package/src/components/utils/popover/popover.const.ts +3 -3
- package/src/full.ts +4 -0
- package/src/stories/Placeholder.stories.ts +7 -2
- package/src/stories/helpers.ts +2 -0
- package/src/styles/main.css +64 -10
- package/src/tools/header/index.ts +307 -26
- package/src/tools/index.ts +3 -1
- package/src/tools/table/index.ts +2 -3
- package/src/tools/table/table-add-controls.ts +29 -1
- package/src/tools/table/table-cell-blocks.ts +93 -0
- package/src/tools/toggle/block-operations.ts +110 -0
- package/src/tools/toggle/constants.ts +49 -0
- package/src/tools/toggle/dom-builder.ts +152 -0
- package/src/tools/toggle/index.ts +302 -0
- package/src/tools/toggle/toggle-keyboard.ts +156 -0
- package/src/tools/toggle/toggle-lifecycle.ts +81 -0
- package/src/tools/toggle/toggle-shortcuts.ts +113 -0
- package/src/tools/toggle/types.ts +21 -0
- package/types/full.d.ts +2 -0
- package/types/tools-entry.d.ts +2 -1
- package/types/utils/popover/popover.d.ts +8 -0
- package/dist/chunks/index-DBWWKrDe.mjs +0 -78
|
@@ -2,22 +2,39 @@ import { twMerge, twJoin } from '../tw';
|
|
|
2
2
|
|
|
3
3
|
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* SVG icons for notification styles.
|
|
7
|
+
* Each icon is 16x16, stroke-based for consistency.
|
|
8
|
+
*/
|
|
9
|
+
const ICONS = {
|
|
10
|
+
success: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M5.5 8.25l1.75 1.75 3.25-3.5"/></svg>`,
|
|
11
|
+
error: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M8 5.25v3"/><circle cx="8" cy="10.75" r="0.5" fill="currentColor" stroke="none"/></svg>`,
|
|
12
|
+
default: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6.25"/><path d="M8 7.25v3.25"/><circle cx="8" cy="5.25" r="0.5" fill="currentColor" stroke="none"/></svg>`,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const CLOSE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 2l6 6M8 2l-6 6"/></svg>`;
|
|
16
|
+
|
|
5
17
|
export const CSS = {
|
|
6
18
|
wrapper: twJoin(
|
|
7
19
|
'fixed z-2 bottom-5 left-5',
|
|
8
20
|
'font-[-apple-system,BlinkMacSystemFont,"Segoe_UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira_Sans","Droid_Sans","Helvetica_Neue",sans-serif]'
|
|
9
21
|
),
|
|
10
22
|
notification: twJoin(
|
|
11
|
-
'relative w-[230px] mt-[15px] py-[13px] px-4',
|
|
12
|
-
'bg-white shadow-notify rounded-[
|
|
13
|
-
'text-sm leading-[1.4em] wrap-break-word',
|
|
23
|
+
'relative flex items-start gap-2.5 w-[230px] mt-[15px] py-[13px] px-4',
|
|
24
|
+
'bg-white shadow-notify rounded-[6px]',
|
|
25
|
+
'text-sm leading-[1.4em] wrap-break-word overflow-hidden',
|
|
14
26
|
'before:content-[""] before:absolute before:block before:top-0 before:left-0',
|
|
15
27
|
'before:w-[3px] before:h-[calc(100%-6px)] before:m-[3px] before:rounded-[5px] before:bg-transparent'
|
|
16
28
|
),
|
|
29
|
+
icon: 'shrink-0 mt-px',
|
|
30
|
+
iconSuccess: 'text-[#34c992]',
|
|
31
|
+
iconError: 'text-[#fb5d5d]',
|
|
32
|
+
iconDefault: 'text-[#9ca3af]',
|
|
33
|
+
messageWrapper: 'flex-1 min-w-0',
|
|
17
34
|
crossBtn: twJoin(
|
|
18
|
-
'absolute top-[7px] right-[
|
|
19
|
-
'
|
|
20
|
-
'
|
|
35
|
+
'absolute top-[7px] right-[7px] flex items-center justify-center',
|
|
36
|
+
'w-6 h-6 rounded opacity-40 cursor-pointer',
|
|
37
|
+
'transition-opacity duration-150',
|
|
21
38
|
'hover:opacity-100'
|
|
22
39
|
),
|
|
23
40
|
btnsWrapper: 'flex flex-row flex-nowrap mt-[5px]',
|
|
@@ -37,6 +54,70 @@ export const CSS = {
|
|
|
37
54
|
'bg-[#fffbfb]!',
|
|
38
55
|
'before:bg-[#fb5d5d]!'
|
|
39
56
|
),
|
|
57
|
+
progressBar: twJoin(
|
|
58
|
+
'absolute bottom-0 left-0 h-[2px] rounded-b-[6px]',
|
|
59
|
+
'animate-notify-progress'
|
|
60
|
+
),
|
|
61
|
+
progressDefault: 'bg-[#d1d5db]',
|
|
62
|
+
progressSuccess: 'bg-[#41ffb1]',
|
|
63
|
+
progressError: 'bg-[#fb5d5d]',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Creates an icon element for the notification.
|
|
68
|
+
*/
|
|
69
|
+
const createIcon = (style?: string): HTMLElement => {
|
|
70
|
+
const iconWrapper = document.createElement('span');
|
|
71
|
+
const resolvedStyle = style === 'success' || style === 'error' ? style : 'default';
|
|
72
|
+
|
|
73
|
+
iconWrapper.innerHTML = ICONS[resolvedStyle];
|
|
74
|
+
iconWrapper.setAttribute('data-blok-testid', 'notification-icon');
|
|
75
|
+
iconWrapper.setAttribute('data-blok-style', resolvedStyle);
|
|
76
|
+
|
|
77
|
+
const iconColorMap: Record<string, string> = {
|
|
78
|
+
success: CSS.iconSuccess,
|
|
79
|
+
error: CSS.iconError,
|
|
80
|
+
default: CSS.iconDefault,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const colorClass = iconColorMap[resolvedStyle] ?? CSS.iconDefault;
|
|
84
|
+
|
|
85
|
+
iconWrapper.className = twJoin(CSS.icon, colorClass);
|
|
86
|
+
|
|
87
|
+
return iconWrapper;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Creates a close (cross) button with an SVG icon.
|
|
92
|
+
*/
|
|
93
|
+
const createCloseButton = (): HTMLElement => {
|
|
94
|
+
const cross = document.createElement('div');
|
|
95
|
+
|
|
96
|
+
cross.className = CSS.crossBtn;
|
|
97
|
+
cross.setAttribute('data-blok-testid', 'notification-cross');
|
|
98
|
+
cross.innerHTML = CLOSE_ICON;
|
|
99
|
+
|
|
100
|
+
return cross;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Creates a progress bar element for auto-dismissing alerts.
|
|
105
|
+
*/
|
|
106
|
+
export const createProgressBar = (style?: string, time?: number): HTMLElement => {
|
|
107
|
+
const bar = document.createElement('div');
|
|
108
|
+
|
|
109
|
+
const progressColorMap: Record<string, string> = {
|
|
110
|
+
success: CSS.progressSuccess,
|
|
111
|
+
error: CSS.progressError,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const colorClass = progressColorMap[style ?? ''] ?? CSS.progressDefault;
|
|
115
|
+
|
|
116
|
+
bar.className = twJoin(CSS.progressBar, colorClass);
|
|
117
|
+
bar.setAttribute('data-blok-testid', 'notification-progress');
|
|
118
|
+
bar.style.animationDuration = `${time ?? 8000}ms`;
|
|
119
|
+
|
|
120
|
+
return bar;
|
|
40
121
|
};
|
|
41
122
|
|
|
42
123
|
/**
|
|
@@ -45,8 +126,6 @@ export const CSS = {
|
|
|
45
126
|
*/
|
|
46
127
|
export const alert = (options: NotifierOptions): HTMLElement => {
|
|
47
128
|
const notify = document.createElement('DIV');
|
|
48
|
-
const cross = document.createElement('DIV');
|
|
49
|
-
const message = options.message;
|
|
50
129
|
const style = options.style;
|
|
51
130
|
|
|
52
131
|
const getStyleClasses = (): string => {
|
|
@@ -69,12 +148,23 @@ export const alert = (options: NotifierOptions): HTMLElement => {
|
|
|
69
148
|
notify.setAttribute('data-blok-testid', 'notification');
|
|
70
149
|
}
|
|
71
150
|
|
|
72
|
-
|
|
151
|
+
// Icon
|
|
152
|
+
const icon = createIcon(style);
|
|
73
153
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
154
|
+
notify.appendChild(icon);
|
|
155
|
+
|
|
156
|
+
// Message wrapper (flex child that holds message + buttons)
|
|
157
|
+
const messageWrapper = document.createElement('div');
|
|
158
|
+
|
|
159
|
+
messageWrapper.className = CSS.messageWrapper;
|
|
160
|
+
messageWrapper.setAttribute('data-blok-testid', 'notification-message');
|
|
161
|
+
messageWrapper.innerHTML = options.message;
|
|
162
|
+
notify.appendChild(messageWrapper);
|
|
163
|
+
|
|
164
|
+
// Close button
|
|
165
|
+
const cross = createCloseButton();
|
|
77
166
|
|
|
167
|
+
cross.addEventListener('click', () => notify.remove());
|
|
78
168
|
notify.appendChild(cross);
|
|
79
169
|
|
|
80
170
|
return notify;
|
|
@@ -86,6 +176,7 @@ export const alert = (options: NotifierOptions): HTMLElement => {
|
|
|
86
176
|
*/
|
|
87
177
|
export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
88
178
|
const notify = alert(options);
|
|
179
|
+
const messageWrapper = notify.querySelector('[data-blok-testid="notification-message"]') as HTMLElement;
|
|
89
180
|
const btnsWrapper = document.createElement('div');
|
|
90
181
|
const okBtn = document.createElement('button');
|
|
91
182
|
const cancelBtn = document.createElement('button');
|
|
@@ -123,7 +214,12 @@ export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
|
123
214
|
btnsWrapper.appendChild(okBtn);
|
|
124
215
|
btnsWrapper.appendChild(cancelBtn);
|
|
125
216
|
|
|
126
|
-
|
|
217
|
+
// Append buttons to the message wrapper so they flow under the message text
|
|
218
|
+
if (messageWrapper) {
|
|
219
|
+
messageWrapper.appendChild(btnsWrapper);
|
|
220
|
+
} else {
|
|
221
|
+
notify.appendChild(btnsWrapper);
|
|
222
|
+
}
|
|
127
223
|
|
|
128
224
|
return notify;
|
|
129
225
|
};
|
|
@@ -134,6 +230,7 @@ export const confirm = (options: ConfirmNotifierOptions): HTMLElement => {
|
|
|
134
230
|
*/
|
|
135
231
|
export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
136
232
|
const notify = alert(options);
|
|
233
|
+
const messageWrapper = notify.querySelector('[data-blok-testid="notification-message"]') as HTMLElement;
|
|
137
234
|
const btnsWrapper = document.createElement('div');
|
|
138
235
|
const okBtn = document.createElement('button');
|
|
139
236
|
const input = document.createElement('input');
|
|
@@ -176,7 +273,12 @@ export const prompt = (options: PromptNotifierOptions): HTMLElement => {
|
|
|
176
273
|
btnsWrapper.appendChild(input);
|
|
177
274
|
btnsWrapper.appendChild(okBtn);
|
|
178
275
|
|
|
179
|
-
|
|
276
|
+
// Append to message wrapper for proper flex layout
|
|
277
|
+
if (messageWrapper) {
|
|
278
|
+
messageWrapper.appendChild(btnsWrapper);
|
|
279
|
+
} else {
|
|
280
|
+
notify.appendChild(btnsWrapper);
|
|
281
|
+
}
|
|
180
282
|
|
|
181
283
|
return notify;
|
|
182
284
|
};
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import { alert, confirm, getWrapper, prompt } from './draw';
|
|
1
|
+
import { alert, confirm, createProgressBar, getWrapper, prompt } from './draw';
|
|
2
2
|
import type { NotifierOptions, ConfirmNotifierOptions, PromptNotifierOptions } from './types';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_TIME = 8000;
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Applies the exit animation and removes the element after it finishes.
|
|
8
|
+
*/
|
|
9
|
+
const dismissWithAnimation = (element: HTMLElement): void => {
|
|
10
|
+
element.classList.add('animate-notify-slide-out');
|
|
11
|
+
|
|
12
|
+
element.addEventListener('animationend', () => {
|
|
13
|
+
element.remove();
|
|
14
|
+
}, { once: true });
|
|
15
|
+
};
|
|
16
|
+
|
|
6
17
|
/**
|
|
7
18
|
* Prepare wrapper for notifications
|
|
8
19
|
* @returns {HTMLElement}
|
|
@@ -48,8 +59,24 @@ export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptN
|
|
|
48
59
|
// type is 'alert' or undefined
|
|
49
60
|
const alertElement = alert(options);
|
|
50
61
|
|
|
62
|
+
// Add progress bar for auto-dismissing alerts
|
|
63
|
+
const progressBar = createProgressBar(options.style, time);
|
|
64
|
+
|
|
65
|
+
alertElement.appendChild(progressBar);
|
|
66
|
+
|
|
67
|
+
// Wire up the close button to use animated dismissal
|
|
68
|
+
const crossBtn = alertElement.querySelector('[data-blok-testid="notification-cross"]');
|
|
69
|
+
|
|
70
|
+
if (crossBtn) {
|
|
71
|
+
// Replace the basic remove handler with animated dismissal
|
|
72
|
+
const newCross = crossBtn.cloneNode(true) as HTMLElement;
|
|
73
|
+
|
|
74
|
+
crossBtn.replaceWith(newCross);
|
|
75
|
+
newCross.addEventListener('click', () => dismissWithAnimation(alertElement));
|
|
76
|
+
}
|
|
77
|
+
|
|
51
78
|
window.setTimeout(() => {
|
|
52
|
-
alertElement
|
|
79
|
+
dismissWithAnimation(alertElement);
|
|
53
80
|
}, time);
|
|
54
81
|
|
|
55
82
|
return alertElement;
|
|
@@ -57,11 +84,11 @@ export const show = (options: NotifierOptions | ConfirmNotifierOptions | PromptN
|
|
|
57
84
|
|
|
58
85
|
if (wrapper && notify) {
|
|
59
86
|
wrapper.appendChild(notify);
|
|
60
|
-
notify.className = `${notify.className} animate-notify-
|
|
87
|
+
notify.className = `${notify.className} animate-notify-slide-in`;
|
|
61
88
|
notify.setAttribute('data-blok-bounce-in', 'true');
|
|
62
89
|
}
|
|
63
90
|
};
|
|
64
91
|
|
|
65
92
|
export const Notifier = {
|
|
66
93
|
show,
|
|
67
|
-
};
|
|
94
|
+
};
|
|
@@ -10,7 +10,7 @@ export const css = {
|
|
|
10
10
|
* Note: noHover state is handled via [data-blok-popover-item-no-hover] which disables hover
|
|
11
11
|
* Priority order: active < hover < focus (focus wins when navigating with keyboard)
|
|
12
12
|
*/
|
|
13
|
-
item: 'flex items-center select-none border-none bg-transparent rounded-
|
|
13
|
+
item: 'flex items-center select-none border-none bg-transparent rounded-lg px-2 py-(--item-padding) text-text-primary mb-0.5 transition-[color,background-color,border-color,opacity,max-height,padding,margin] duration-150 max-h-10 overflow-hidden data-blok-popover-item-active:bg-icon-active-bg data-blok-popover-item-active:text-icon-active-text can-hover:hover:cursor-pointer can-hover:hover:bg-item-hover-bg data-blok-force-hover:cursor-pointer data-blok-force-hover:bg-item-hover-bg data-[blok-focused="true"]:bg-item-focus-bg data-blok-popover-item-no-hover:hover:bg-transparent data-blok-popover-item-no-hover:cursor-default can-hover:data-blok-popover-item-destructive:hover:text-item-destructive-text can-hover:data-blok-popover-item-destructive:hover:bg-item-destructive-hover-bg [&[data-blok-popover-item-destructive][data-blok-force-hover]]:text-item-destructive-text [&[data-blok-popover-item-destructive][data-blok-force-hover]]:bg-item-destructive-hover-bg [&[data-blok-popover-item-destructive][data-blok-focused="true"]]:text-item-destructive-text [&[data-blok-popover-item-destructive][data-blok-focused="true"]]:bg-item-destructive-hover-bg',
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Item disabled state
|
|
@@ -21,7 +21,7 @@ export const css = {
|
|
|
21
21
|
/**
|
|
22
22
|
* Icon container styles
|
|
23
23
|
*/
|
|
24
|
-
icon: 'flex items-center justify-center w-[26px] h-[26px] [&_svg]:w-icon [&_svg]:h-icon',
|
|
24
|
+
icon: 'flex items-center justify-center w-[26px] h-[26px] shrink-0 rounded-lg [&_svg]:w-icon [&_svg]:h-icon',
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Focused state class for DomIterator/Flipper keyboard navigation.
|
|
@@ -258,8 +258,8 @@ export class PopoverItemDefault extends PopoverItem {
|
|
|
258
258
|
const titleEl = document.createElement('div');
|
|
259
259
|
|
|
260
260
|
titleEl.className = params.secondaryLabel
|
|
261
|
-
? 'grow
|
|
262
|
-
: 'mr-auto
|
|
261
|
+
? 'grow whitespace-nowrap text-sm font-medium leading-5'
|
|
262
|
+
: 'mr-auto whitespace-nowrap text-sm font-medium leading-5';
|
|
263
263
|
titleEl.setAttribute(DATA_ATTR.popoverItemTitle, '');
|
|
264
264
|
titleEl.setAttribute('data-blok-testid', 'popover-item-title');
|
|
265
265
|
titleEl.textContent = title;
|
|
@@ -272,7 +272,7 @@ export class PopoverItemDefault extends PopoverItem {
|
|
|
272
272
|
if (params.secondaryLabel) {
|
|
273
273
|
const secondaryEl = document.createElement('div');
|
|
274
274
|
|
|
275
|
-
secondaryEl.className = '
|
|
275
|
+
secondaryEl.className = 'ml-auto shrink-0 flex items-center whitespace-nowrap pl-20 text-[11px] font-medium tracking-wide text-text-secondary/50';
|
|
276
276
|
secondaryEl.setAttribute(DATA_ATTR.popoverItemSecondaryTitle, '');
|
|
277
277
|
secondaryEl.setAttribute('data-blok-testid', 'popover-item-secondary-title');
|
|
278
278
|
secondaryEl.textContent = params.secondaryLabel;
|
|
@@ -326,8 +326,7 @@ export class PopoverItemDefault extends PopoverItem {
|
|
|
326
326
|
|
|
327
327
|
return twMerge(
|
|
328
328
|
css.item,
|
|
329
|
-
|
|
330
|
-
!isInline && !isNestedInline && (this.params.secondaryLabel || (this.hasChildren && !this.isChevronHidden) ? 'pl-2 pr-2' : 'pl-2 pr-8'),
|
|
329
|
+
!isInline && !isNestedInline && 'pl-2 pr-4',
|
|
331
330
|
isInline && cssInline.item,
|
|
332
331
|
isNestedInline && cssNestedInline.item,
|
|
333
332
|
this.params.isDisabled && css.itemDisabled
|
|
@@ -343,6 +342,7 @@ export class PopoverItemDefault extends PopoverItem {
|
|
|
343
342
|
isInline && 'w-auto h-auto [&_svg]:w-icon [&_svg]:h-icon mobile:[&_svg]:w-icon-mobile mobile:[&_svg]:h-icon-mobile',
|
|
344
343
|
isNestedInline && 'w-toolbox-btn h-toolbox-btn',
|
|
345
344
|
iconWithGap && 'mr-3',
|
|
345
|
+
iconWithGap && !isInline && 'bg-icon-bg',
|
|
346
346
|
iconWithGap && isInline && 'shadow-none bg-transparent mr-0!',
|
|
347
347
|
iconWithGap && isNestedInline && 'mr-2!',
|
|
348
348
|
isWobbling && 'animate-wobble'
|
|
@@ -384,10 +384,10 @@ export class PopoverItemDefault extends PopoverItem {
|
|
|
384
384
|
|
|
385
385
|
if (isHidden) {
|
|
386
386
|
this.nodes.root.setAttribute(DATA_ATTR.hidden, 'true');
|
|
387
|
-
this.nodes.root.classList.add('
|
|
387
|
+
this.nodes.root.classList.add('opacity-0', 'max-h-0!', 'py-0!', 'mb-0!');
|
|
388
388
|
} else {
|
|
389
389
|
this.nodes.root.removeAttribute(DATA_ATTR.hidden);
|
|
390
|
-
this.nodes.root.classList.remove('
|
|
390
|
+
this.nodes.root.classList.remove('opacity-0', 'max-h-0!', 'py-0!', 'mb-0!');
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Tailwind CSS classes for popover separator component
|
|
3
3
|
*/
|
|
4
4
|
export const css = {
|
|
5
|
-
container: 'py-1 px-[3px]',
|
|
6
|
-
containerHidden: '
|
|
5
|
+
container: 'py-1 px-[3px] transition-[opacity,max-height,padding] duration-150 max-h-4 overflow-hidden',
|
|
6
|
+
containerHidden: 'opacity-0 max-h-0! py-0!',
|
|
7
7
|
line: 'h-px w-full bg-popover-border',
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* CSS class names to be used in popover search input class
|
|
3
3
|
*/
|
|
4
4
|
export const css = {
|
|
5
|
-
wrapper: 'bg-[#F8F8F8] border border-[rgba(226,226,229,0.20)] rounded-
|
|
5
|
+
wrapper: 'bg-[#F8F8F8] border border-[rgba(226,226,229,0.20)] rounded-lg p-0.5 grid grid-cols-[auto_auto_1fr] grid-rows-[auto] transition-colors duration-150 focus-within:bg-white focus-within:border-[rgba(56,138,229,0.3)]',
|
|
6
6
|
icon: 'w-toolbox-btn h-toolbox-btn flex items-center justify-center mr-2 [&_svg]:w-icon [&_svg]:h-icon [&_svg]:text-gray-text',
|
|
7
7
|
input: "text-sm outline-hidden font-medium font-inherit border-0 bg-transparent m-0 p-0 leading-[22px] min-w-[calc(100%-(--spacing(6))-10px)] placeholder:text-gray-text placeholder:font-medium",
|
|
8
8
|
};
|
|
@@ -391,9 +391,11 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|
|
391
391
|
protected toggleNothingFoundMessage(isDisplayed: boolean): void {
|
|
392
392
|
if (isDisplayed) {
|
|
393
393
|
this.nodes.nothingFoundMessage.classList.remove('hidden');
|
|
394
|
+
this.nodes.nothingFoundMessage.classList.add('animate-[fade-in_150ms_ease_forwards]');
|
|
394
395
|
this.nodes.nothingFoundMessage.setAttribute(DATA_ATTR.nothingFoundDisplayed, 'true');
|
|
395
396
|
} else {
|
|
396
397
|
this.nodes.nothingFoundMessage.classList.add('hidden');
|
|
398
|
+
this.nodes.nothingFoundMessage.classList.remove('animate-[fade-in_150ms_ease_forwards]');
|
|
397
399
|
this.nodes.nothingFoundMessage.removeAttribute(DATA_ATTR.nothingFoundDisplayed);
|
|
398
400
|
}
|
|
399
401
|
}
|
|
@@ -449,11 +451,12 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|
|
449
451
|
|
|
450
452
|
// Set CSS variables
|
|
451
453
|
popover.style.setProperty('--width', this.params.width ?? 'auto');
|
|
452
|
-
popover.style.setProperty('--item-padding', '
|
|
454
|
+
popover.style.setProperty('--item-padding', '4px');
|
|
453
455
|
popover.style.setProperty('--item-height', 'calc(1.25rem + 2 * var(--item-padding))');
|
|
454
456
|
popover.style.setProperty('--popover-top', 'calc(100% + 0.5rem)');
|
|
455
457
|
popover.style.setProperty('--popover-left', '0');
|
|
456
458
|
popover.style.setProperty('--nested-popover-overlap', '0.25rem');
|
|
459
|
+
popover.style.setProperty('--max-height', '400px');
|
|
457
460
|
|
|
458
461
|
// Create popover container
|
|
459
462
|
const popoverContainer = document.createElement('div');
|
|
@@ -464,7 +467,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|
|
464
467
|
// Create nothing found message
|
|
465
468
|
const nothingFoundMessage = document.createElement('div');
|
|
466
469
|
nothingFoundMessage.className = twMerge(
|
|
467
|
-
'cursor-default text-sm leading-5 font-medium whitespace-nowrap overflow-hidden text-ellipsis text-gray-text
|
|
470
|
+
'cursor-default text-sm leading-5 font-medium whitespace-nowrap overflow-hidden text-ellipsis text-gray-text px-3 py-3 text-center',
|
|
468
471
|
'hidden'
|
|
469
472
|
);
|
|
470
473
|
nothingFoundMessage.setAttribute('data-blok-testid', 'popover-nothing-found');
|
|
@@ -60,6 +60,12 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
60
60
|
*/
|
|
61
61
|
private trigger: HTMLElement | undefined;
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Optional element whose left edge is used for horizontal positioning
|
|
65
|
+
* instead of the trigger's left edge.
|
|
66
|
+
*/
|
|
67
|
+
private leftAlignElement: HTMLElement | undefined;
|
|
68
|
+
|
|
63
69
|
/**
|
|
64
70
|
* Popover size cache
|
|
65
71
|
*/
|
|
@@ -78,6 +84,10 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
78
84
|
this.trigger = params.trigger;
|
|
79
85
|
}
|
|
80
86
|
|
|
87
|
+
if (params.leftAlignElement) {
|
|
88
|
+
this.leftAlignElement = params.leftAlignElement;
|
|
89
|
+
}
|
|
90
|
+
|
|
81
91
|
if (params.nestingLevel !== undefined) {
|
|
82
92
|
this.nestingLevel = params.nestingLevel;
|
|
83
93
|
}
|
|
@@ -191,7 +201,13 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
191
201
|
this.nodes.popover.style.setProperty(CSSVariables.PopoverLeft, '0px');
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
|
|
204
|
+
const measuredSize = this.size;
|
|
205
|
+
|
|
206
|
+
this.nodes.popover.style.setProperty(CSSVariables.PopoverHeight, measuredSize.height + 'px');
|
|
207
|
+
|
|
208
|
+
if (this.params.width === undefined || this.params.width === 'auto') {
|
|
209
|
+
this.nodes.popover.style.setProperty('--width', measuredSize.width + 'px');
|
|
210
|
+
}
|
|
195
211
|
|
|
196
212
|
if (!this.trigger && !this.shouldOpenBottom) {
|
|
197
213
|
this.setOpenTop(true);
|
|
@@ -270,7 +286,7 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
270
286
|
(rect.top - offset - popoverRect.height > window.scrollY);
|
|
271
287
|
const top = shouldFlipTop ? rect.top - offset - popoverRect.height + window.scrollY : initialTop;
|
|
272
288
|
|
|
273
|
-
const initialLeft = rect.left + window.scrollX;
|
|
289
|
+
const initialLeft = (this.leftAlignElement?.getBoundingClientRect().left ?? rect.left) + window.scrollX;
|
|
274
290
|
const shouldFlipLeft = initialLeft + popoverRect.width > windowWidth + window.scrollX;
|
|
275
291
|
const left = shouldFlipLeft ? Math.max(0, rect.right - popoverRect.width + window.scrollX) : initialLeft;
|
|
276
292
|
|
|
@@ -695,6 +711,18 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
695
711
|
// Cast data.items to PopoverItemDefault[] since we know that's what filterItems passes
|
|
696
712
|
const matchingItems = data.items as unknown as PopoverItemDefault[];
|
|
697
713
|
|
|
714
|
+
/**
|
|
715
|
+
* When nothing is found, disable transitions so items hide instantly.
|
|
716
|
+
* The "Nothing found" message fade-in provides the visual transition;
|
|
717
|
+
* animating the last items' collapse simultaneously causes a jarring
|
|
718
|
+
* height bounce in the popover container.
|
|
719
|
+
*/
|
|
720
|
+
if (isNothingFound) {
|
|
721
|
+
this.items.forEach(item => {
|
|
722
|
+
item.getElement()?.style.setProperty('transition-duration', '0s');
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
|
|
698
726
|
this.items
|
|
699
727
|
.forEach((item) => {
|
|
700
728
|
const isDefaultItem = item instanceof PopoverItemDefault;
|
|
@@ -705,6 +733,15 @@ export class PopoverDesktop extends PopoverAbstract {
|
|
|
705
733
|
|
|
706
734
|
item.toggleHidden(isHidden);
|
|
707
735
|
});
|
|
736
|
+
|
|
737
|
+
if (isNothingFound) {
|
|
738
|
+
// Force reflow so the instant hide takes effect, then restore transitions
|
|
739
|
+
this.nodes.popoverContainer.offsetHeight;
|
|
740
|
+
this.items.forEach(item => {
|
|
741
|
+
item.getElement()?.style.removeProperty('transition-duration');
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
|
|
708
745
|
this.toggleNothingFoundMessage(isNothingFound);
|
|
709
746
|
|
|
710
747
|
/** List of elements available for keyboard navigation considering search query applied */
|
|
@@ -5,19 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const css = {
|
|
7
7
|
// Popover container - base styles
|
|
8
|
-
popoverContainer: 'absolute flex flex-col overflow-hidden box-border opacity-0 pointer-events-none p-0 border-none z-4 max-h-0 min-w-(--width) w-(--width) rounded-
|
|
8
|
+
popoverContainer: 'absolute flex flex-col overflow-hidden box-border opacity-0 pointer-events-none p-0 border-none z-4 max-h-0 min-w-(--width) w-(--width) rounded-xl shadow-[0_4px_20px_-4px_var(--color-popover-shadow),0_0_0_0.5px_rgba(0,0,0,0.06)] left-(--popover-left) top-(--popover-top) bg-popover-bg',
|
|
9
9
|
|
|
10
10
|
// Popover container - mobile styles (applied conditionally)
|
|
11
11
|
// Reset left/top from base class since inset shorthand may not properly override them in twMerge
|
|
12
12
|
popoverContainerMobile: 'fixed max-w-none rounded-[10px] min-w-[calc(100%-var(--offset)*2)] left-auto top-auto inset-[auto_var(--offset)_calc(var(--offset)+env(safe-area-inset-bottom))_var(--offset)]',
|
|
13
13
|
|
|
14
14
|
// Popover container - opened state
|
|
15
|
-
popoverContainerOpened: 'opacity-100 pointer-events-auto p-1 max-h-(--max-height) border border-popover-border animate-[panelShowing_100ms_ease]',
|
|
15
|
+
popoverContainerOpened: 'opacity-100 pointer-events-auto p-1.5 max-h-(--max-height) border border-popover-border animate-[panelShowing_100ms_ease]',
|
|
16
16
|
|
|
17
17
|
// Popover overlay
|
|
18
18
|
popoverOverlay: 'hidden bg-dark',
|
|
19
19
|
|
|
20
|
-
items: 'overflow-y-auto overscroll-contain',
|
|
20
|
+
items: 'overflow-y-auto overscroll-contain [scrollbar-gutter:stable] pr-1',
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/**
|
package/src/full.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { BoldInlineTool as Bold } from './components/inline-tools/inline-tool-bold';
|
|
19
19
|
import { ItalicInlineTool as Italic } from './components/inline-tools/inline-tool-italic';
|
|
20
20
|
import { LinkInlineTool as Link } from './components/inline-tools/inline-tool-link';
|
|
21
|
+
import { MarkerInlineTool as Marker } from './components/inline-tools/inline-tool-marker';
|
|
21
22
|
import { Header } from './tools/header';
|
|
22
23
|
import { ListItem as List } from './tools/list';
|
|
23
24
|
import { Paragraph } from './tools/paragraph';
|
|
@@ -29,9 +30,11 @@ export {
|
|
|
29
30
|
Paragraph,
|
|
30
31
|
Header,
|
|
31
32
|
List,
|
|
33
|
+
Toggle,
|
|
32
34
|
Bold,
|
|
33
35
|
Italic,
|
|
34
36
|
Link,
|
|
37
|
+
Marker,
|
|
35
38
|
defaultBlockTools,
|
|
36
39
|
defaultInlineTools,
|
|
37
40
|
} from './tools';
|
|
@@ -66,4 +69,5 @@ export const allTools = {
|
|
|
66
69
|
bold: { class: Bold },
|
|
67
70
|
italic: { class: Italic },
|
|
68
71
|
link: { class: Link },
|
|
72
|
+
marker: { class: Marker },
|
|
69
73
|
} as const;
|
|
@@ -171,10 +171,15 @@ export const TypeAndClearPlaceholder: Story = {
|
|
|
171
171
|
|
|
172
172
|
if (contentEditable) {
|
|
173
173
|
await userEvent.click(contentEditable);
|
|
174
|
-
await userEvent.
|
|
174
|
+
await userEvent.keyboard('Hello world');
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
await waitFor(
|
|
178
|
+
() => {
|
|
179
|
+
expect(contentEditable?.textContent).toContain('Hello world');
|
|
180
|
+
},
|
|
181
|
+
TIMEOUT_ACTION
|
|
182
|
+
);
|
|
178
183
|
});
|
|
179
184
|
|
|
180
185
|
await step('Clear content to restore placeholder', async () => {
|
package/src/stories/helpers.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { BoldInlineTool } from '../components/inline-tools/inline-tool-bold';
|
|
|
8
8
|
import { ConvertInlineTool } from '../components/inline-tools/inline-tool-convert';
|
|
9
9
|
import { ItalicInlineTool } from '../components/inline-tools/inline-tool-italic';
|
|
10
10
|
import { LinkInlineTool } from '../components/inline-tools/inline-tool-link';
|
|
11
|
+
import { MarkerInlineTool } from '../components/inline-tools/inline-tool-marker';
|
|
11
12
|
import { Header } from '../tools/header';
|
|
12
13
|
import { ListItem } from '../tools/list';
|
|
13
14
|
import { Paragraph } from '../tools/paragraph';
|
|
@@ -35,6 +36,7 @@ export const defaultTools: { [toolName: string]: ToolConstructable | ToolSetting
|
|
|
35
36
|
bold: BoldInlineTool,
|
|
36
37
|
italic: ItalicInlineTool,
|
|
37
38
|
link: LinkInlineTool,
|
|
39
|
+
marker: MarkerInlineTool,
|
|
38
40
|
convertTo: ConvertInlineTool,
|
|
39
41
|
};
|
|
40
42
|
|