@ryuzaki13/react-foundation-ui 3.0.1 → 3.1.1
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/COLOR_TOKENS_MIGRATION.md +72 -56
- package/README.md +9 -14
- package/dist/chunks/badge-6mXO9BWP.js.map +1 -1
- package/dist/chunks/ui.module-oRwY3Zli.js.map +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tag-input/index.js.map +1 -1
- package/package.json +1 -1
- package/src/styles/_tone-derived.scss +36 -0
- package/src/styles/mixins/_controls.scss +3 -7
- package/src/styles/mixins/controls.test.ts +25 -0
- package/src/styles/themes/_interactive-surface.scss +6 -6
- package/src/styles/themes/_theme.scss +50 -18
- package/src/styles/themes/theme.test.ts +81 -14
- package/storybook-static/assets/{Badge-CPJUZBAx.js → Badge-DZyhbbM8.js} +1 -1
- package/storybook-static/assets/{Badge.stories-BV9Ob_Oc.js → Badge.stories-NTzzKHJp.js} +1 -1
- package/storybook-static/assets/{BadgeList-CtdWGEn6.js → BadgeList-CyZwXD1B.js} +1 -1
- package/storybook-static/assets/{BarcodeScannerDialog.stories-B_wBhs1h.js → BarcodeScannerDialog.stories-DgsYBggs.js} +1 -1
- package/storybook-static/assets/{Button-DJgPWpef.js → Button-CH_Z6sO1.js} +1 -1
- package/storybook-static/assets/{Button-BO03YvyD.js → Button-CljTMz3I.js} +1 -1
- package/storybook-static/assets/{Button.stories-DhqncZmo.js → Button.stories-BewKK-DS.js} +1 -1
- package/storybook-static/assets/{CalendarView-Ctgt0vSh.js → CalendarView--x2hpT2q.js} +1 -1
- package/storybook-static/assets/{CheckBox-x4MtRKCD.js → CheckBox-DXh75fAR.js} +1 -1
- package/storybook-static/assets/{CheckBox-BOIYiJm5.js → CheckBox-LimJi0UQ.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-B-YhjVpn.js → CheckBox.stories-o6rpfweF.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-D2hSJGdc.js → Color-6AOWCN3U-8n8FCLyC.js} +1 -1
- package/storybook-static/assets/{ContextMenu-ConDIkSx.js → ContextMenu-6TfxDPWB.js} +1 -1
- package/storybook-static/assets/{ContextMenu--tEb29lb.js → ContextMenu-Ck4m7ukO.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-DdZB2dQb.js → ContextMenu.stories-C0bTUdLv.js} +1 -1
- package/storybook-static/assets/{CustomOptionButton-D9_PjL0f.js → CustomOptionButton-dg-hYBoR.js} +1 -1
- package/storybook-static/assets/{DateInput-D1XJQ-6l.js → DateInput-B_V47xx7.js} +1 -1
- package/storybook-static/assets/{DateInput-Dh0ZTlaK.js → DateInput-jn0KyIGr.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-YIy6ns7j.js → DateInput.stories-v7jSkTQz.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-Xy9xMJwE.js → DateRangePresetSelect-B2r12dtb.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-CfCtwULa.js → DateRangePresetSelect-CSJ_ADhT.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-Cp8bCPPr.js → DateRangePresetSelect.stories-BkIZ7BYP.js} +1 -1
- package/storybook-static/assets/{Detail-V4a7PEQy.js → Detail-CGNKKZy_.js} +1 -1
- package/storybook-static/assets/{Detail.stories-CaltBUzP.js → Detail.stories-C9LpPn0-.js} +1 -1
- package/storybook-static/assets/{Dialog-TBOx7xuG.js → Dialog-ChVT8EA-.js} +1 -1
- package/storybook-static/assets/{Dialog-CwIJrdeS.js → Dialog-DOZ6KRDZ.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-BWXw_XOW.js → Dialog.stories-_ir2h3DS.js} +1 -1
- package/storybook-static/assets/{Disclosure-ptHsbm71.js → Disclosure-DhYXxm-s.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-CG2LclkF.js → Disclosure.stories-d5gH0j1X.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-CseVXRGI.js → DisclosureGroup-CJzrTBA5.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-Cz6wf1E5.js → DocsRenderer-JROSPFPF-4c9XFCUP.js} +1 -1
- package/storybook-static/assets/{DropZone-CRai68J2.js → DropZone-CAlPFkgO.js} +1 -1
- package/storybook-static/assets/{DropZone-D_zss6IH.js → DropZone-C_ONrNnf.js} +1 -1
- package/storybook-static/assets/{DropZone.stories-DieoYknx.js → DropZone.stories-CIa7HYSk.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-BojaSt_0.js → DropdownMenu-DWPIbyYd.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-BiS2kSkL.js → ExpandableActionPanel-Dpv7Ogiv.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-CMaKcNjZ.js → ExpandableActionPanel.stories-DO_6Ariv.js} +1 -1
- package/storybook-static/assets/{Flex-4xyVvQjb.js → Flex-DeOiILWd.js} +1 -1
- package/storybook-static/assets/{Flex.stories-C3tQavbS.js → Flex.stories-Dhs5mlVY.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-D-hgsDWB.js → FloatingPopover-0Dprr5jf.js} +1 -1
- package/storybook-static/assets/{FormattedTableCell-BIx_wHxt.js → FormattedTableCell-qL4-wkCE.js} +1 -1
- package/storybook-static/assets/{Grid-D_tQSQsa.js → Grid-C8DgxK3U.js} +1 -1
- package/storybook-static/assets/{Grid.stories-rm-LBWqc.js → Grid.stories-BrapZKvO.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-TWj6EUhv.js → ImageCropper.stories-CHYm4PqH.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-fJY5cwIZ.js → ImageRenderer-CbHQ_5di.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-COWaXJSu.js → ImageRenderer.stories-CgFX5vX1.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-CarFyXxF.js → ImageView.stories-B66Y0y8Z.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-WwLkgsZl.js → ImageViewer.stories-Dr8hSJB4.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-Dg1heG9I.js → ImageViewerRuntime-ChNDRkbL.js} +1 -1
- package/storybook-static/assets/{Input-BqipFubD.js → Input-7Olx6bGm.js} +1 -1
- package/storybook-static/assets/{Input-CRMRR0du.js → Input-C3tV6aOt.js} +1 -1
- package/storybook-static/assets/{Input.stories-BZBQd_Yo.js → Input.stories-Bp7kBh2f.js} +1 -1
- package/storybook-static/assets/{InputDateTime-BKzFQcD2.js → InputDateTime-DFMMt-mf.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-B3dXU0or.js → InputDateTime.stories-Dds2W8yW.js} +1 -1
- package/storybook-static/assets/{InputFile-C3iCB2fV.js → InputFile-Ba-RwZsI.js} +1 -1
- package/storybook-static/assets/{InputFile-Dl4khE53.js → InputFile-DSu8gm8A.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-DYqlThPW.js → InputFile.stories-YGXOc3DO.js} +1 -1
- package/storybook-static/assets/{InputFiles-CWyvWdT6.js → InputFiles-CIPsyfH5.js} +1 -1
- package/storybook-static/assets/{InputFiles-fSWRgPQt.js → InputFiles-DqlQJsmm.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-wwrSxxCj.js → InputFiles.stories-BH_gwOug.js} +1 -1
- package/storybook-static/assets/{InputFilesList-dPZoA3cU.js → InputFilesList-BEDe42dK.js} +1 -1
- package/storybook-static/assets/{InputImage-DbK6OW82.js → InputImage-BdcxBj6J.js} +1 -1
- package/storybook-static/assets/{InputImage-hI2j2ETf.js → InputImage-D4D-X8Ys.js} +1 -1
- package/storybook-static/assets/{InputImage.stories-BmjAuHh6.js → InputImage.stories-BOW5PRM7.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-CP9rMbrV.js → InteractiveComponents-hi2rc0Cm.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents.stories-DWGP7kN9.js → InteractiveComponents.stories-5hPeC7R2.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-B6l0KM01.js → LayoutPicker-BO18SpK7.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-BqPt4z1o.js → LayoutPicker-BqGACXDe.js} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-CobjDPnt.js → LayoutPicker.stories-BlN_ODG4.js} +1 -1
- package/storybook-static/assets/{Listbox-D8wHXixj.js → Listbox-4PvVEZRh.js} +1 -1
- package/storybook-static/assets/{Listbox-VYmcGjMI.js → Listbox-Bta1Rvnl.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-DwGQUQ0i.js → Listbox.stories-DtEb9pou.js} +1 -1
- package/storybook-static/assets/{Modal-gdYxFkXo.js → Modal-Bmxp4mLU.js} +1 -1
- package/storybook-static/assets/{Modal-J__v8Hop.js → Modal-BwdW99av.js} +1 -1
- package/storybook-static/assets/{Modal.stories-DIs97N2U.js → Modal.stories-DuNdaLN2.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-LwIYImtY.js → ModalManagerProvider-CGmNKOlv.js} +1 -1
- package/storybook-static/assets/{MultiSelect-DoJsmrgD.js → MultiSelect-BrHYXgvm.js} +1 -1
- package/storybook-static/assets/{MultiSelect-DxLtgKfo.js → MultiSelect-enRkbUVu.js} +1 -1
- package/storybook-static/assets/{MultiSelect.stories-gbsa3dqJ.js → MultiSelect.stories-4SSQVsBu.js} +1 -1
- package/storybook-static/assets/{NoData-o_sLpPoU.js → NoData-Bdkk4qX-.js} +1 -1
- package/storybook-static/assets/{NotificationsHost-BMBxunA0.js → NotificationsHost-epLriMYO.js} +1 -1
- package/storybook-static/assets/{NotificationsHost.stories-BzoCtqMU.js → NotificationsHost.stories-DvF1HMJp.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect-CcbmxqpZ.js → ODataMultiSelect-DYrfAdLn.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-zw67beZc.js → ODataMultiSelect.stories-DVkerQKn.js} +1 -1
- package/storybook-static/assets/{ODataSelect-CXW8j-z7.js → ODataSelect-DWJYlxQc.js} +1 -1
- package/storybook-static/assets/{ODataSelect.stories-TQM6_DYK.js → ODataSelect.stories-CywUlhAN.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect-DGF8-pWk.js → ODataTreeMultiSelect-D90IEf3K.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-Dd_0ra7b.js → ODataTreeMultiSelect.stories-CadVRCl9.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-VuBknyZd.js → ODataTreeSelect-DSAGCoD4.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-BtzFf_u0.js → ODataTreeSelect.stories-BEA_Vb7u.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-DZNxJvgJ.js → OneStepScroller-CCIUc14k.js} +1 -1
- package/storybook-static/assets/{Option-B4DvYPy2.js → Option-ByR48EZl.js} +1 -1
- package/storybook-static/assets/{OptionButton-C4VuB9n6.js → OptionButton-BMoBnbt6.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DSxwgwCW.js → PeriodSelect-C-eGa-Kg.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-B8ox22dv.js → PeriodSelect-sUUZBBze.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-CjTMQdsC.js → PeriodSelect.stories-CEPqnZQz.js} +1 -1
- package/storybook-static/assets/{PickerField-CIzr66S8.js → PickerField-EVQAudL9.js} +1 -1
- package/storybook-static/assets/{PickerTriggerActions-jZXgVj2i.js → PickerTriggerActions-Da3NAgN3.js} +1 -1
- package/storybook-static/assets/{Popover-CtpYUZz7.js → Popover-B7-sfEHt.js} +1 -1
- package/storybook-static/assets/{Popover-BpC72C2z.js → Popover-MG_TKcDM.js} +1 -1
- package/storybook-static/assets/{Popover.stories-BujYLT_N.js → Popover.stories-6rqdsIci.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-C6Y1OPu2.js → PresetRangeDateInput-XkeUUy4t.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-v5tpwKOr.js → PresetRangeDateInput-oJU3yjjY.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-DXJi-hz8.js → PresetRangeDateInput.stories-CYja7SlF.js} +1 -1
- package/storybook-static/assets/{PresetSelect-gK2K5zkH.js → PresetSelect-DWW52rEr.js} +1 -1
- package/storybook-static/assets/{README-BsO3rGAo.js → README-3onNI8KH.js} +1 -1
- package/storybook-static/assets/{README-DjHS3LyZ.js → README-8TyDLZ8m.js} +1 -1
- package/storybook-static/assets/{README-C9WDex0g.js → README-B-dL4Dp1.js} +1 -1
- package/storybook-static/assets/{README-Dj-J1DiV.js → README-B64nG4-r.js} +1 -1
- package/storybook-static/assets/{README-CEg7RhiN.js → README-B887wTp_.js} +1 -1
- package/storybook-static/assets/{README-BFt1rK1m.js → README-BGGr2zYm.js} +1 -1
- package/storybook-static/assets/{README-ZeIvwrze.js → README-BIp15sbA.js} +1 -1
- package/storybook-static/assets/{README-BovclOxj.js → README-BLjBIG5b.js} +1 -1
- package/storybook-static/assets/{README-Cm8APMxg.js → README-BSDrP24w.js} +1 -1
- package/storybook-static/assets/{README-BUvT1PC3.js → README-BUXHrder.js} +1 -1
- package/storybook-static/assets/{README-35Rz4zJn.js → README-BXK6R512.js} +1 -1
- package/storybook-static/assets/{README-CrMVq7Lw.js → README-Bd8oZSBv.js} +1 -1
- package/storybook-static/assets/{README-BeUl88Dw.js → README-BeQQlzku.js} +1 -1
- package/storybook-static/assets/{README-Cgz1iUWg.js → README-Bk_j-FWx.js} +1 -1
- package/storybook-static/assets/{README-fC8saBR0.js → README-BqbscBiw.js} +1 -1
- package/storybook-static/assets/{README-BNk4sKbP.js → README-BtXLkUYG.js} +1 -1
- package/storybook-static/assets/{README-DOgmLyjE.js → README-BuyFnGUr.js} +1 -1
- package/storybook-static/assets/{README-CV2hDek-.js → README-C4aCrDhQ.js} +1 -1
- package/storybook-static/assets/{README-BPeCkxf5.js → README-C5Evi_Od.js} +1 -1
- package/storybook-static/assets/{README-ByB4pX-h.js → README-C5o1ee9L.js} +1 -1
- package/storybook-static/assets/{README-tSD_oNwO.js → README-C87LZz6f.js} +1 -1
- package/storybook-static/assets/{README-DFnpGGTR.js → README-CNQEzBHn.js} +1 -1
- package/storybook-static/assets/{README-DwIqFkLN.js → README-CarOmnk7.js} +1 -1
- package/storybook-static/assets/{README-BEvGMEjK.js → README-CeZpJRtg.js} +1 -1
- package/storybook-static/assets/{README-DtFIYO3L.js → README-ChG5rY0i.js} +1 -1
- package/storybook-static/assets/{README-C0ZKA9b-.js → README-Co2u6-Lj.js} +1 -1
- package/storybook-static/assets/{README-PVmZhf60.js → README-CoIps3ow.js} +1 -1
- package/storybook-static/assets/{README-DUr25qzJ.js → README-CpE19mEd.js} +1 -1
- package/storybook-static/assets/{README-p3wyWaCG.js → README-CzeEqZV4.js} +1 -1
- package/storybook-static/assets/{README-DgvV1tz2.js → README-D8RATsxd.js} +1 -1
- package/storybook-static/assets/{README-tWeRF96t.js → README-DCcgaFeQ.js} +1 -1
- package/storybook-static/assets/{README-BNb4F90Z.js → README-DDIuwU7m.js} +1 -1
- package/storybook-static/assets/{README-BWp5_vwI.js → README-DGvtRCkM.js} +1 -1
- package/storybook-static/assets/{README-CGVpfLua.js → README-DJnq2r66.js} +1 -1
- package/storybook-static/assets/{README-BJ9k0Np6.js → README-DM_g6PCr.js} +1 -1
- package/storybook-static/assets/{README-BARPT1_b.js → README-DN4AcFXT.js} +1 -1
- package/storybook-static/assets/{README-CHLqXECy.js → README-DS6WZRoh.js} +1 -1
- package/storybook-static/assets/{README-DKn16Q4N.js → README-DgYioDAa.js} +1 -1
- package/storybook-static/assets/{README-BkP5HRKY.js → README-DoB-J219.js} +1 -1
- package/storybook-static/assets/{README-SLh2SkXm.js → README-DoW41pj8.js} +1 -1
- package/storybook-static/assets/{README-Uy_ptFqX.js → README-DousuaoR.js} +1 -1
- package/storybook-static/assets/{README-76skvum6.js → README-DpPmQc1C.js} +1 -1
- package/storybook-static/assets/{README-DjuBYSZf.js → README-HiFT84zG.js} +1 -1
- package/storybook-static/assets/{README-CYI_EOl0.js → README-LkMYQQZG.js} +1 -1
- package/storybook-static/assets/{README-Dd4omKy5.js → README-N-t9Esrs.js} +1 -1
- package/storybook-static/assets/{README-DWdFUqVy.js → README-Q6TktIyC.js} +1 -1
- package/storybook-static/assets/{README-CJazQDMs.js → README-ZBSgAfUQ.js} +1 -1
- package/storybook-static/assets/{README-BC0N2gII.js → README-aMioowWA.js} +1 -1
- package/storybook-static/assets/{README-C7xESdeZ.js → README-bp2jvuhN.js} +1 -1
- package/storybook-static/assets/{README-BN7MT2Ap.js → README-dBjUPcUC.js} +1 -1
- package/storybook-static/assets/{README-DTSAWBmg.js → README-jAXiQfWd.js} +1 -1
- package/storybook-static/assets/{README-9FkDpJNL.js → README-kqacqwMO.js} +1 -1
- package/storybook-static/assets/{README-Daf_hy33.js → README-px0sy3mH.js} +1 -1
- package/storybook-static/assets/{RadioButton-SQQ0XZh_.js → RadioButton-CBZ-2tpg.js} +1 -1
- package/storybook-static/assets/{RadioButton-D-hGkjCE.js → RadioButton-DeU7LySy.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-y_RgH92I.js → RadioButton.stories-DzBmcWYh.js} +1 -1
- package/storybook-static/assets/{RadioGroup-c4001gHC.js → RadioGroup-9L9EBmPZ.js} +1 -1
- package/storybook-static/assets/{RadioGroup-BbZbR0Nd.js → RadioGroup-M8U_3Qu1.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-VUC3P22Z.js → RadioGroup.stories-DhaRdRnV.js} +1 -1
- package/storybook-static/assets/{Scrollable-BCbWuy4A.js → Scrollable-DKD8_GYW.js} +1 -1
- package/storybook-static/assets/{Select-B9E7ahIl.js → Select-DG_lx7Rl.js} +1 -1
- package/storybook-static/assets/{Select-CJ33Sv-J.js → Select-Dg-l0yoE.js} +1 -1
- package/storybook-static/assets/{Select.stories-BcAnEbEn.js → Select.stories-D4TelGYC.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-BPS2hfyJ.js → SerializableSelect-CpitM8WL.js} +1 -1
- package/storybook-static/assets/{SerializableSelect.stories-CM1ncPEp.js → SerializableSelect.stories-ZlWgKkHt.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-BHYCHJQE.js → SingleDateTimeInput-CqocRYJY.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-gTTeUwQu.js → SingleDateTimeInput-m6jYz_r2.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput.stories-CbmsCFpW.js → SingleDateTimeInput.stories-fH-iW9qA.js} +1 -1
- package/storybook-static/assets/{Slider-CGKqjm7X.js → Slider-CF5lNqVZ.js} +1 -1
- package/storybook-static/assets/{Slider-RBZi0g2K.js → Slider-D0Qwf7EY.js} +1 -1
- package/storybook-static/assets/{Slider.stories-PSyMsLLp.js → Slider.stories-B6QVVtrd.js} +1 -1
- package/storybook-static/assets/{SliderInput-Df9TmEKF.js → SliderInput-Dvz_4kgc.js} +1 -1
- package/storybook-static/assets/{SliderInput-CznPoK1l.js → SliderInput-zM3jF5KD.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-BQiRt7bg.js → SliderInput.stories-BKuUv8N2.js} +1 -1
- package/storybook-static/assets/{Sortable-D42YEoo9.js → Sortable-C0K_6g4P.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-DkJeEE-A.js → Sortable.stories-Chf1sxZg.js} +1 -1
- package/storybook-static/assets/{Splitter-DlRtVvJG.js → Splitter-B8Ksf_xs.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-CWV7Ofeq.js → Splitter.stories-fRvGX5Jp.js} +1 -1
- package/storybook-static/assets/{StateSelect-Cx2e1djS.js → StateSelect-CPNphBga.js} +1 -1
- package/storybook-static/assets/{StateSelect-DSmcFkB_.js → StateSelect-CjsviCtb.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-DE36S04p.js → StateSelect.stories-D32llZ6v.js} +1 -1
- package/storybook-static/assets/{StatusIndicator-5q4RVrlX.js → StatusIndicator-CKvd7tHs.js} +1 -1
- package/storybook-static/assets/{StatusIndicator.stories-ChoX8YBt.js → StatusIndicator.stories-NOvPPe_7.js} +1 -1
- package/storybook-static/assets/{StringToggle.stories-C3yjPy-u.js → StringToggle.stories-Bicdqe7C.js} +1 -1
- package/storybook-static/assets/{Switch-BVC4Fwd3.js → Switch-Bkob6qYu.js} +1 -1
- package/storybook-static/assets/{Switch-AbpldWAB.js → Switch-C61_o5be.js} +1 -1
- package/storybook-static/assets/{Switch.stories-FPuGI2wa.js → Switch.stories-BSXuhd1n.js} +1 -1
- package/storybook-static/assets/{Table-Supenh30.js → Table-DrI-ye5w.js} +1 -1
- package/storybook-static/assets/{Table.stories-DF5hgk3V.js → Table.stories-DfeiRj00.js} +1 -1
- package/storybook-static/assets/{TableEditor.stories-CNBIQyHL.js → TableEditor.stories-BsLxmTao.js} +1 -1
- package/storybook-static/assets/{Tabs-C039OI9y.js → Tabs-CgalbGPu.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-B49PmfdF.js → Tabs.stories-BNjq8-Q7.js} +1 -1
- package/storybook-static/assets/{TabsBox-C3l5eozp.js → TabsBox-CpmFgUBj.js} +1 -1
- package/storybook-static/assets/{TagInput-CwyrBnFS.js → TagInput-DvEYa96d.js} +1 -1
- package/storybook-static/assets/{TagInput.stories-coxQ7Em9.js → TagInput.stories-j4Qd29sb.js} +1 -1
- package/storybook-static/assets/{Text-Ci8EVxdT.js → Text-BZ1JvyUT.js} +1 -1
- package/storybook-static/assets/{Textarea-BcSflD0g.js → Textarea-BMzsyo3c.js} +1 -1
- package/storybook-static/assets/{Textarea-CK323Zvt.js → Textarea-BRdIBUkE.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-DksBPbfd.js → Textarea.stories-C0x425GI.js} +1 -1
- package/storybook-static/assets/{TimePanel-rc26nbZr.js → TimePanel-BWqMMKMh.js} +1 -1
- package/storybook-static/assets/{TimePanel.stories-CX33HFgH.js → TimePanel.stories-DyU92R36.js} +1 -1
- package/storybook-static/assets/{Toggle-Dj9mjhm6.js → Toggle-Bownsch8.js} +1 -1
- package/storybook-static/assets/{Toggle-BJ6a2rYs.js → Toggle-ClbrIGCZ.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-D2U9YqcP.js → Toggle.stories-DsNHF5oC.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-cRTpzovV.js → TreeMultiSelect-CDg35T0c.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-0bsShZqq.js → TreeMultiSelect-D3TzNY3n.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect.stories-BGX0KlJq.js → TreeMultiSelect.stories-C3xbNKlw.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-BWuxoc3q.js → TreePickerBase-DwM3HHNJ.js} +1 -1
- package/storybook-static/assets/{TreeSelect-BJ9bYsyd.js → TreeSelect-BWZkUyfN.js} +1 -1
- package/storybook-static/assets/{TreeSelect-K8QcuBmM.js → TreeSelect-CzPMpXEN.js} +1 -1
- package/storybook-static/assets/{TreeSelect.stories-DGVst2IK.js → TreeSelect.stories-Dt2iVzbQ.js} +1 -1
- package/storybook-static/assets/{TreeTable-BqgD-2_7.js → TreeTable-CVn34tY8.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-BcXMrgLT.js → TreeTable.stories-D1ufYTtN.js} +1 -1
- package/storybook-static/assets/{blocks-COtaqhG7.js → blocks-BIDgFZzT.js} +3 -3
- package/storybook-static/assets/{check-ATe9qlhZ.js → check-Ci14Psj_.js} +1 -1
- package/storybook-static/assets/{chevron-down-C8rhgH0F.js → chevron-down-DbAd2qk7.js} +1 -1
- package/storybook-static/assets/{chevron-left-BREifQyg.js → chevron-left-BkXE-6hJ.js} +1 -1
- package/storybook-static/assets/{chevron-right-2G3N5a4T.js → chevron-right--BJBL7es.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-CseeqzDY.js → chunk-W22LQPXL-Ck7Hq2hD.js} +1 -1
- package/storybook-static/assets/{circle-alert-BA5kPpt-.js → circle-alert-DZ-mqRo-.js} +1 -1
- package/storybook-static/assets/{circle-check-Cs9mMZi_.js → circle-check-ohYPmGXF.js} +1 -1
- package/storybook-static/assets/{components-C3kWCR3K.js → components-BcLNCNYh.js} +3 -3
- package/storybook-static/assets/{contextMenu-BoM0Rrc0.js → contextMenu-CV1L1k-X.js} +1 -1
- package/storybook-static/assets/{download-LnWJpQGc.js → download-Cj6p8bKz.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-5ooru93I.js → floating-ui.react-BSdrfXIW.js} +1 -1
- package/storybook-static/assets/{foundationApi-BBE0Q757.js → foundationApi-CQ7TLs4F.js} +1 -1
- package/storybook-static/assets/{foundationLib-B08SbcPW.js → foundationLib-CrDmX7bX.js} +1 -1
- package/storybook-static/assets/{hooks-C0EM5QXj.js → hooks-DUyI2f7Z.js} +1 -1
- package/storybook-static/assets/{iframe-BT_jngkf.css → iframe-C-4tNqTX.css} +1 -1
- package/storybook-static/assets/iframe-CBug5Z2-.js +1 -0
- package/storybook-static/assets/{iframe-Dyg5pyjI.js → iframe-CLqd5Giv.js} +3 -3
- package/storybook-static/assets/{info-CwIwVUF0.js → info-T_PVPfD-.js} +1 -1
- package/storybook-static/assets/{odata-DhMoO1-z.js → odata-CCaj8ulC.js} +1 -1
- package/storybook-static/assets/{odataStoryFixtures-gWL6AhyF.js → odataStoryFixtures-Bv9BrgZv.js} +1 -1
- package/storybook-static/assets/{react-DKmCseal.js → react-Ce_aQozh.js} +1 -1
- package/storybook-static/assets/{refresh-cw-cEegR14X.js → refresh-cw-CNrDNE_N.js} +1 -1
- package/storybook-static/assets/{settings-2-fhEteCrb.js → settings-2-jAEe_Y9H.js} +1 -1
- package/storybook-static/assets/{sortable-Dn0xMPIF.js → sortable-kVkmtF5b.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-BSkd404o.js → syntaxhighlighter-QEQV7K2Y-zKIOKo3C.js} +1 -1
- package/storybook-static/assets/{trash-2-DAG4_F6W.js → trash-2-Dt4QzFcm.js} +1 -1
- package/storybook-static/assets/{triangle-alert-5OwD01Sy.js → triangle-alert-BiyO16L3.js} +1 -1
- package/storybook-static/assets/{ui-DSS1yTEO.css → ui-DPTWro6M.css} +1 -1
- package/storybook-static/assets/{uiClasses-e9OQfdw2.js → uiClasses-BY4mQ-J3.js} +1 -1
- package/storybook-static/assets/{useODataSelectBase-BKD8wc02.js → useODataSelectBase-DpSBp8Rk.js} +1 -1
- package/storybook-static/assets/{useODataTreeData-VIqPm8lR.js → useODataTreeData-ynwGta5X.js} +1 -1
- package/storybook-static/assets/{usePickerQuery-qXXh72-v.js → usePickerQuery-BVMhh3cw.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-DbTYgg-I.js → usePickerTriggerController-TTKRTNy4.js} +1 -1
- package/storybook-static/assets/{x-sWfOdOu5.js → x-wBEq3sjm.js} +1 -1
- package/storybook-static/iframe.html +3 -3
- package/storybook-static/project.json +1 -1
- package/storybook-static/assets/iframe-B5Pyh1le.js +0 -1
- /package/storybook-static/assets/{ui.module-SH8ehXul.js → ui.module-B6Lc_ii5.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Замена цветовых токенов
|
|
2
2
|
|
|
3
|
-
Новый контракт темы содержит семь схем: `accent`, `brand`, `neutral`, `error`, `warning`, `success`, `info`. Каждая схема
|
|
3
|
+
Новый контракт темы содержит семь схем: `accent`, `brand`, `neutral`, `error`, `warning`, `success`, `info`. Каждая схема принимает четыре настраиваемые роли:
|
|
4
4
|
|
|
5
5
|
- `--<tone>-text` — текст и иконка на обычной поверхности;
|
|
6
6
|
- `--<tone>-border` — рамка;
|
|
@@ -40,57 +40,57 @@
|
|
|
40
40
|
|
|
41
41
|
## Производные состояния
|
|
42
42
|
|
|
43
|
-
Hover, active и soft
|
|
43
|
+
Hover, active и soft не входят в карту `status`, но снова доступны как публичные генерируемые CSS-токены. UI-пакет вычисляет их через единые `color-mix(in srgb, ...)` из четырёх основных ролей. Карта `tokens` имеет наивысший compile-time приоритет, если приложению действительно требуется точное переопределение. Базовые роли, общие границы, производные состояния и `tokens` сначала объединяются в одну Sass-карту, поэтому совпадающий ключ заменяется до генерации CSS и объявляется в theme selector ровно один раз.
|
|
44
44
|
|
|
45
45
|
```text
|
|
46
|
-
--status-brand-text-hover:
|
|
47
|
-
--status-brand-text-active:
|
|
48
|
-
--status-brand-border-hover:
|
|
49
|
-
--status-brand-border-active:
|
|
46
|
+
--status-brand-text-hover: --brand-text-hover
|
|
47
|
+
--status-brand-text-active: --brand-text-active
|
|
48
|
+
--status-brand-border-hover: --brand-border-hover
|
|
49
|
+
--status-brand-border-active: --brand-border-active
|
|
50
50
|
--status-brand-border-focus: --focus-ring
|
|
51
|
-
--status-brand-fill-hover:
|
|
52
|
-
--status-brand-fill-active:
|
|
53
|
-
--status-brand-soft:
|
|
54
|
-
--status-neutral-text-hover:
|
|
55
|
-
--status-neutral-text-active:
|
|
56
|
-
--status-neutral-border-hover:
|
|
57
|
-
--status-neutral-border-active:
|
|
51
|
+
--status-brand-fill-hover: --brand-fill-hover
|
|
52
|
+
--status-brand-fill-active: --brand-fill-active
|
|
53
|
+
--status-brand-soft: --brand-soft
|
|
54
|
+
--status-neutral-text-hover: --neutral-text-hover
|
|
55
|
+
--status-neutral-text-active: --neutral-text-active
|
|
56
|
+
--status-neutral-border-hover: --neutral-border-hover
|
|
57
|
+
--status-neutral-border-active: --neutral-border-active
|
|
58
58
|
--status-neutral-border-focus: --focus-ring
|
|
59
|
-
--status-neutral-fill-hover:
|
|
60
|
-
--status-neutral-fill-active:
|
|
61
|
-
--status-neutral-soft:
|
|
62
|
-
--status-error-text-hover:
|
|
63
|
-
--status-error-text-active:
|
|
64
|
-
--status-error-border-hover:
|
|
65
|
-
--status-error-border-active:
|
|
59
|
+
--status-neutral-fill-hover: --neutral-fill-hover
|
|
60
|
+
--status-neutral-fill-active: --neutral-fill-active
|
|
61
|
+
--status-neutral-soft: --neutral-soft
|
|
62
|
+
--status-error-text-hover: --error-text-hover
|
|
63
|
+
--status-error-text-active: --error-text-active
|
|
64
|
+
--status-error-border-hover: --error-border-hover
|
|
65
|
+
--status-error-border-active: --error-border-active
|
|
66
66
|
--status-error-border-focus: --focus-ring
|
|
67
|
-
--status-error-fill-hover:
|
|
68
|
-
--status-error-fill-active:
|
|
69
|
-
--status-error-soft:
|
|
70
|
-
--status-warning-text-hover:
|
|
71
|
-
--status-warning-text-active:
|
|
72
|
-
--status-warning-border-hover:
|
|
73
|
-
--status-warning-border-active:
|
|
67
|
+
--status-error-fill-hover: --error-fill-hover
|
|
68
|
+
--status-error-fill-active: --error-fill-active
|
|
69
|
+
--status-error-soft: --error-soft
|
|
70
|
+
--status-warning-text-hover: --warning-text-hover
|
|
71
|
+
--status-warning-text-active: --warning-text-active
|
|
72
|
+
--status-warning-border-hover: --warning-border-hover
|
|
73
|
+
--status-warning-border-active: --warning-border-active
|
|
74
74
|
--status-warning-border-focus: --focus-ring
|
|
75
|
-
--status-warning-fill-hover:
|
|
76
|
-
--status-warning-fill-active:
|
|
77
|
-
--status-warning-soft:
|
|
78
|
-
--status-success-text-hover:
|
|
79
|
-
--status-success-text-active:
|
|
80
|
-
--status-success-border-hover:
|
|
81
|
-
--status-success-border-active:
|
|
75
|
+
--status-warning-fill-hover: --warning-fill-hover
|
|
76
|
+
--status-warning-fill-active: --warning-fill-active
|
|
77
|
+
--status-warning-soft: --warning-soft
|
|
78
|
+
--status-success-text-hover: --success-text-hover
|
|
79
|
+
--status-success-text-active: --success-text-active
|
|
80
|
+
--status-success-border-hover: --success-border-hover
|
|
81
|
+
--status-success-border-active: --success-border-active
|
|
82
82
|
--status-success-border-focus: --focus-ring
|
|
83
|
-
--status-success-fill-hover:
|
|
84
|
-
--status-success-fill-active:
|
|
85
|
-
--status-success-soft:
|
|
86
|
-
--status-info-text-hover:
|
|
87
|
-
--status-info-text-active:
|
|
88
|
-
--status-info-border-hover:
|
|
89
|
-
--status-info-border-active:
|
|
83
|
+
--status-success-fill-hover: --success-fill-hover
|
|
84
|
+
--status-success-fill-active: --success-fill-active
|
|
85
|
+
--status-success-soft: --success-soft
|
|
86
|
+
--status-info-text-hover: --info-text-hover
|
|
87
|
+
--status-info-text-active: --info-text-active
|
|
88
|
+
--status-info-border-hover: --info-border-hover
|
|
89
|
+
--status-info-border-active: --info-border-active
|
|
90
90
|
--status-info-border-focus: --focus-ring
|
|
91
|
-
--status-info-fill-hover:
|
|
92
|
-
--status-info-fill-active:
|
|
93
|
-
--status-info-soft:
|
|
91
|
+
--status-info-fill-hover: --info-fill-hover
|
|
92
|
+
--status-info-fill-active: --info-fill-active
|
|
93
|
+
--status-info-soft: --info-soft
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
## Accent и прежние interactive-токены
|
|
@@ -102,18 +102,20 @@ Hover, active и soft больше не являются токенами тем
|
|
|
102
102
|
--interactive-color: удалён; обычное свойство color самого компонента
|
|
103
103
|
--interactive-surface: удалён; обычное свойство background-color самого компонента
|
|
104
104
|
--interactive-border: удалён; обычное свойство border-color самого компонента
|
|
105
|
-
--interactive-hover-color: --accent-
|
|
106
|
-
--interactive-active-color: --accent-
|
|
105
|
+
--interactive-hover-color: --accent-text-hover
|
|
106
|
+
--interactive-active-color: --accent-text-active
|
|
107
107
|
--interactive-selected-color: --accent-on-fill
|
|
108
|
-
--interactive-hover-surface: --accent-fill
|
|
109
|
-
--interactive-active-surface: --accent-fill
|
|
108
|
+
--interactive-hover-surface: --accent-fill-hover
|
|
109
|
+
--interactive-active-surface: --accent-fill-active
|
|
110
110
|
--interactive-selected-surface: --accent-fill
|
|
111
|
-
--interactive-hover-border: --accent-border
|
|
112
|
-
--interactive-active-border: --accent-border
|
|
111
|
+
--interactive-hover-border: --accent-border-hover
|
|
112
|
+
--interactive-active-border: --accent-border-active
|
|
113
113
|
--interactive-selected-border: --accent-border
|
|
114
114
|
отсутствовал: --accent-on-fill
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
`interactiveSurface` использует производные `--accent-*-hover` и `--accent-*-active` для одноимённых интерактивных состояний. Выбранное состояние остаётся устойчивым заполненным состоянием и использует базовые `--accent-fill`, `--accent-border` и `--accent-on-fill`.
|
|
118
|
+
|
|
117
119
|
## High contrast
|
|
118
120
|
|
|
119
121
|
```text
|
|
@@ -121,32 +123,32 @@ Hover, active и soft больше не являются токенами тем
|
|
|
121
123
|
--hc-status-brand-border: --hc-brand-border
|
|
122
124
|
--hc-status-brand-fill: --hc-brand-fill
|
|
123
125
|
--hc-status-brand-on-fill: --hc-brand-on-fill
|
|
124
|
-
--hc-status-brand-soft: удалён;
|
|
126
|
+
--hc-status-brand-soft: удалён; --brand-soft вычисляется из high-contrast-aware --brand-fill
|
|
125
127
|
--hc-status-neutral-text: --hc-neutral-text
|
|
126
128
|
--hc-status-neutral-border: --hc-neutral-border
|
|
127
129
|
--hc-status-neutral-fill: --hc-neutral-fill
|
|
128
130
|
--hc-status-neutral-on-fill: --hc-neutral-on-fill
|
|
129
|
-
--hc-status-neutral-soft: удалён;
|
|
131
|
+
--hc-status-neutral-soft: удалён; --neutral-soft вычисляется из high-contrast-aware --neutral-fill
|
|
130
132
|
--hc-status-error-text: --hc-error-text
|
|
131
133
|
--hc-status-error-border: --hc-error-border
|
|
132
134
|
--hc-status-error-fill: --hc-error-fill
|
|
133
135
|
--hc-status-error-on-fill: --hc-error-on-fill
|
|
134
|
-
--hc-status-error-soft: удалён;
|
|
136
|
+
--hc-status-error-soft: удалён; --error-soft вычисляется из high-contrast-aware --error-fill
|
|
135
137
|
--hc-status-warning-text: --hc-warning-text
|
|
136
138
|
--hc-status-warning-border: --hc-warning-border
|
|
137
139
|
--hc-status-warning-fill: --hc-warning-fill
|
|
138
140
|
--hc-status-warning-on-fill: --hc-warning-on-fill
|
|
139
|
-
--hc-status-warning-soft: удалён;
|
|
141
|
+
--hc-status-warning-soft: удалён; --warning-soft вычисляется из high-contrast-aware --warning-fill
|
|
140
142
|
--hc-status-success-text: --hc-success-text
|
|
141
143
|
--hc-status-success-border: --hc-success-border
|
|
142
144
|
--hc-status-success-fill: --hc-success-fill
|
|
143
145
|
--hc-status-success-on-fill: --hc-success-on-fill
|
|
144
|
-
--hc-status-success-soft: удалён;
|
|
146
|
+
--hc-status-success-soft: удалён; --success-soft вычисляется из high-contrast-aware --success-fill
|
|
145
147
|
--hc-status-info-text: --hc-info-text
|
|
146
148
|
--hc-status-info-border: --hc-info-border
|
|
147
149
|
--hc-status-info-fill: --hc-info-fill
|
|
148
150
|
--hc-status-info-on-fill: --hc-info-on-fill
|
|
149
|
-
--hc-status-info-soft: удалён;
|
|
151
|
+
--hc-status-info-soft: удалён; --info-soft вычисляется из high-contrast-aware --info-fill
|
|
150
152
|
|
|
151
153
|
--hc-content-accent: --hc-accent-text
|
|
152
154
|
--hc-border-accent: --hc-accent-border
|
|
@@ -200,6 +202,20 @@ Hover, active и soft больше не являются токенами тем
|
|
|
200
202
|
--info-on-fill
|
|
201
203
|
```
|
|
202
204
|
|
|
205
|
+
Для каждой из семи схем `--<tone>-*` дополнительно выводятся производные токены:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
--<tone>-text-hover
|
|
209
|
+
--<tone>-text-active
|
|
210
|
+
--<tone>-border-hover
|
|
211
|
+
--<tone>-border-active
|
|
212
|
+
--<tone>-fill-hover
|
|
213
|
+
--<tone>-fill-active
|
|
214
|
+
--<tone>-soft
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Эти 49 значений не являются входом Sass-карты `status`. Отдельные `--hc-<tone>-*` для них не нужны: формулы используют первичные токены, которые уже учитывают high-contrast overrides.
|
|
218
|
+
|
|
203
219
|
Первичное объявление каждого цвета имеет форму `--token: var(--hc-token, #hex)`. Это правило автоматически применяется к цветовым значениям в картах `tokens` и `status`. Contrast-режим задаёт только `--hc-*`, а обычная тема продолжает использовать hex fallback.
|
|
204
220
|
|
|
205
221
|
## Sass-конфигурация
|
package/README.md
CHANGED
|
@@ -108,9 +108,13 @@ import "@ryuzaki13/react-foundation-ui/styles.css";
|
|
|
108
108
|
|
|
109
109
|
### Точные палитры host-приложения
|
|
110
110
|
|
|
111
|
-
Публичный mixin `theme` принимает обычные hex-цвета для семантических схем `accent`, `brand`, `neutral`, `error`, `warning`, `success` и `info`. У каждой схемы четыре обязательные роли: `text`, `border`, `fill` и `on-fill`. Неуказанные значения наследуются из baseline выбранного light/dark-режима, поэтому host может переопределить одну роль без копирования всей палитры.
|
|
111
|
+
Публичный mixin `theme` принимает обычные hex-цвета для семантических схем `accent`, `brand`, `neutral`, `error`, `warning`, `success` и `info`. У каждой схемы четыре обязательные настраиваемые роли: `text`, `border`, `fill` и `on-fill`. Неуказанные значения наследуются из baseline выбранного light/dark-режима, поэтому host может переопределить одну роль без копирования всей палитры.
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
Из четырёх ролей тема автоматически выводит переиспользуемые токены `--<tone>-text-hover`, `--<tone>-text-active`, `--<tone>-border-hover`, `--<tone>-border-active`, `--<tone>-fill-hover`, `--<tone>-fill-active` и `--<tone>-soft`. Host не передаёт их в карту `status`: единые формулы остаются владельцем UI-пакета, а прикладные стили используют готовые переменные без локального повторения `color-mix(...)`. Appearance-specific состояния вроде ghost и disabled остаются внутри соответствующих UI-компонентов.
|
|
114
|
+
|
|
115
|
+
Mixin `ui-tone()` применяет те же формулы локально, а не ссылается на унаследованное вычисленное значение. Благодаря этому component-scoped переопределение базовой роли, например `--brand-fill`, продолжает влиять на состояния конкретного контрола.
|
|
116
|
+
|
|
117
|
+
Каждый первичный цветовой токен использует одноимённый high-contrast token перед hex fallback: например, `--error-text: var(--hc-error-text, #b91c1c)`. Цветовые значения из карты `tokens` получают такой wrapper автоматически. Это позволяет будущему contrast-режиму заменить палитру без повторной компиляции темы. Производные состояния ссылаются на базовые CSS-переменные, поэтому учитывают их переопределения в том же theme selector. Карта `tokens` имеет наивысший compile-time приоритет и остаётся escape hatch для редкого точного override любого токена. UI-пакет объединяет базовые роли, границы, производные состояния и `tokens` до генерации CSS, поэтому каждое итоговое custom property объявляется в theme selector ровно один раз.
|
|
114
118
|
|
|
115
119
|
```scss
|
|
116
120
|
@use "@ryuzaki13/react-foundation-ui/styles/themes" as foundationThemes;
|
|
@@ -143,7 +147,7 @@ import "@ryuzaki13/react-foundation-ui/styles.css";
|
|
|
143
147
|
}
|
|
144
148
|
```
|
|
145
149
|
|
|
146
|
-
`accent` больше не является отдельной экспериментальной системой `--interactive-*`: это полноценная семантическая схема с теми же четырьмя ролями.
|
|
150
|
+
`accent` больше не является отдельной экспериментальной системой `--interactive-*`: это полноценная семантическая схема с теми же четырьмя ролями. Интерактивные поверхности используют её производные роли для hover/active и базовые роли для устойчивого selected-состояния. Полная карта переименований вынесена в `COLOR_TOKENS_MIGRATION.md`.
|
|
147
151
|
|
|
148
152
|
## Сканирование штрихкодов
|
|
149
153
|
|
|
@@ -152,10 +156,7 @@ Subpath `@ryuzaki13/react-foundation-ui/barcode-scanner` предоставля
|
|
|
152
156
|
```tsx
|
|
153
157
|
import { useState } from "react";
|
|
154
158
|
|
|
155
|
-
import {
|
|
156
|
-
BarcodeScannerDialog,
|
|
157
|
-
type BarcodeScanResult
|
|
158
|
-
} from "@ryuzaki13/react-foundation-ui/barcode-scanner";
|
|
159
|
+
import { BarcodeScannerDialog, type BarcodeScanResult } from "@ryuzaki13/react-foundation-ui/barcode-scanner";
|
|
159
160
|
|
|
160
161
|
export function BarcodeField() {
|
|
161
162
|
const [opened, setOpened] = useState(false);
|
|
@@ -221,13 +222,7 @@ export function MaterialGallery() {
|
|
|
221
222
|
<button type="button" onClick={() => setOpen(true)}>
|
|
222
223
|
Открыть галерею
|
|
223
224
|
</button>
|
|
224
|
-
<ImageViewer
|
|
225
|
-
open={open}
|
|
226
|
-
images={images}
|
|
227
|
-
index={index}
|
|
228
|
-
onIndexChange={setIndex}
|
|
229
|
-
onClose={() => setOpen(false)}
|
|
230
|
-
/>
|
|
225
|
+
<ImageViewer open={open} images={images} index={index} onIndexChange={setIndex} onClose={() => setOpen(false)} />
|
|
231
226
|
</>
|
|
232
227
|
);
|
|
233
228
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge-6mXO9BWP.js","names":[],"sources":["../../src/badge/Badge.module.scss","../../src/badge/Badge.tsx","../../src/badge/BadgeList.tsx"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n\n.badge {\n\t@include ui-static-surface;\n\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tmax-width: 100%;\n\tpadding: 0 var(--space-xs);\n\n\tfont-weight: 500;\n\tfont-variation-settings: \"wght\" 500;\n\tvertical-align: middle;\n}\n\n.passive {\n\tpointer-events: none;\n\tuser-select: none;\n}\n\n.sizeXs {\n\tfont-size: var(--font-size-xs);\n}\n\n.sizeSm {\n\tfont-size: var(--font-size-sm);\n}\n\n.sizeMd {\n\tfont-size: var(--font-size-md);\n}\n\n.sizeLg {\n\tfont-size: var(--font-size-lg);\n}\n\n.sizeXl {\n\tfont-size: var(--font-size-xl);\n}\n\n.content {\n\tmin-width: 0;\n}\n\n.removeButton {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 1.25em;\n\theight: 1.25em;\n\tpadding: 0;\n\tborder: none;\n\tborder-radius: var(--radius-xs);\n\tbackground: transparent;\n\tcolor: inherit;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease,\n\t\tscale var(--transition-fast) ease;\n\n\t&:hover {\n\t\
|
|
1
|
+
{"version":3,"file":"badge-6mXO9BWP.js","names":[],"sources":["../../src/badge/Badge.module.scss","../../src/badge/Badge.tsx","../../src/badge/BadgeList.tsx"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n@use \"@/styles/tone-derived\" as toneDerived;\n\n.badge {\n\t@include ui-static-surface;\n\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tmax-width: 100%;\n\tpadding: 0 var(--space-xs);\n\n\tfont-weight: 500;\n\tfont-variation-settings: \"wght\" 500;\n\tvertical-align: middle;\n}\n\n.passive {\n\tpointer-events: none;\n\tuser-select: none;\n}\n\n.sizeXs {\n\tfont-size: var(--font-size-xs);\n}\n\n.sizeSm {\n\tfont-size: var(--font-size-sm);\n}\n\n.sizeMd {\n\tfont-size: var(--font-size-md);\n}\n\n.sizeLg {\n\tfont-size: var(--font-size-lg);\n}\n\n.sizeXl {\n\tfont-size: var(--font-size-xl);\n}\n\n.content {\n\tmin-width: 0;\n}\n\n.removeButton {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: 1.25em;\n\theight: 1.25em;\n\tpadding: 0;\n\tborder: none;\n\tborder-radius: var(--radius-xs);\n\tbackground: transparent;\n\tcolor: inherit;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease,\n\t\tscale var(--transition-fast) ease;\n\n\t&:hover {\n\t\t@include toneDerived.tone-soft-declaration(\"background-color\", \"error\");\n\t\tcolor: var(--error-text);\n\t\tscale: 1.1;\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n\n\tsvg {\n\t\tdisplay: block;\n\t}\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport { TextOverflow } from \"../text\";\nimport { getUiAppearanceClassName, getUiToneClassName, resolveUiScheme } from \"../uiClasses\";\n\nimport styles from \"./Badge.module.scss\";\n\nimport type { UiAppearance, UiSize, UiTone } from \"../types\";\n\ntype BadgeSize = UiSize;\ntype BadgeAppearance = UiAppearance;\n\ntype BadgeProps = {\n\tchildren: string | number;\n\tsize?: BadgeSize;\n\ttone?: UiTone;\n\tappearance?: BadgeAppearance;\n\tclassName?: string;\n\tonRemove?: () => void;\n};\n\nconst sizeClasses: Record<BadgeSize, string> = {\n\txs: styles.sizeXs,\n\tsm: styles.sizeSm,\n\tmd: styles.sizeMd,\n\tlg: styles.sizeLg,\n\txl: styles.sizeXl\n};\n\n/**\n * Компактный индикатор для статусов, категорий и коротких служебных меток.\n */\nexport function Badge({ children, size = \"sm\", tone, appearance, className, onRemove }: BadgeProps) {\n\tconst fallbackTone = tone ?? \"neutral\";\n\tconst fallbackAppearance = fallbackTone !== \"neutral\" ? \"solid\" : \"outline\";\n\tconst scheme = resolveUiScheme({\n\t\ttone,\n\t\tappearance,\n\t\tfallbackTone,\n\t\tfallbackAppearance\n\t});\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\tstyles.badge,\n\t\t\t\tsizeClasses[size],\n\t\t\t\tgetUiToneClassName(scheme.tone),\n\t\t\t\tgetUiAppearanceClassName(scheme.appearance),\n\t\t\t\t!onRemove && styles.passive,\n\t\t\t\tclassName\n\t\t\t)}>\n\t\t\t<TextOverflow maxChar={25} placement=\"top\" block textWrapProps={{ className: styles.content }}>\n\t\t\t\t{String(children)}\n\t\t\t</TextOverflow>\n\t\t\t{onRemove && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={onRemove}\n\t\t\t\t\tclassName={styles.removeButton}\n\t\t\t\t\taria-label=\"Удалить бейдж\"\n\t\t\t\t\tdata-ui=\"badge-remove-button\"\n\t\t\t\t\tdata-action=\"remove-badge\">\n\t\t\t\t\t<XIcon />\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { Children, Fragment, ReactElement } from \"react\";\n\nimport { FlexContainer } from \"../flex\";\n\nimport { Badge } from \"./Badge\";\n\ninterface BadgeListProps {\n\tchildren: ReactElement<typeof Badge | null | undefined | false>[];\n}\n\n/**\n * Контейнер для группы `Badge`, который выстраивает элементы в единый список с предсказуемыми отступами. Используется для компактного вывода набора меток или фильтров.\n */\nexport function BadgeList({ children }: BadgeListProps) {\n\treturn (\n\t\t<FlexContainer inline wrap gap=\"sm\" align=\"baseline\">\n\t\t\t{Children.map(children, (badge, index) => (\n\t\t\t\t<Fragment key={index}>{badge}</Fragment>\n\t\t\t))}\n\t\t</FlexContainer>\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;GCsBM,IAAyC;CAC9C,IAAI,EAAO;CACX,IAAI,EAAO;CACX,IAAI,EAAO;CACX,IAAI,EAAO;CACX,IAAI,EAAO;AACZ;AAKA,SAAgB,EAAM,EAAE,aAAU,UAAO,MAAM,SAAM,eAAY,cAAW,eAAwB;CACnG,IAAM,IAAe,KAAQ,WAEvB,IAAS,EAAgB;EAC9B;EACA;EACA;EACA,oBAL0B,MAAiB,YAAsB,YAAV;CAMxD,CAAC;CAED,OACC,kBAAC,OAAD;EACC,WAAW,EACV,EAAO,OACP,EAAY,IACZ,EAAmB,EAAO,IAAI,GAC9B,EAAyB,EAAO,UAAU,GAC1C,CAAC,KAAY,EAAO,SACpB,CACD;EARD,UAAA,CASC,kBAAC,GAAD;GAAc,SAAS;GAAI,WAAU;GAAM,OAAA;GAAM,eAAe,EAAE,WAAW,EAAO,QAAQ;GAC1F,UAAA,OAAO,CAAQ;EACH,CAAA,GACb,KACA,kBAAC,UAAD;GACC,MAAK;GACL,SAAS;GACT,WAAW,EAAO;GAClB,cAAW;GACX,WAAQ;GACR,eAAY;GACZ,UAAA,kBAAC,GAAD,CAAQ,CAAA;EACD,CAAA,CAEL;;AAEP;;;ACxDA,SAAgB,EAAU,EAAE,eAA4B;CACvD,OACC,kBAAC,GAAD;EAAe,QAAA;EAAO,MAAA;EAAK,KAAI;EAAK,OAAM;EACxC,UAAA,EAAS,IAAI,IAAW,GAAO,MAC/B,kBAAC,GAAD,EAAA,UAAuB,EAAgB,GAAxB,CAAwB,CACvC;CACa,CAAA;AAEjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.module-oRwY3Zli.js","names":[],"sources":["../../src/ui.module.scss"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n\n.uiSizable {\n\t--base-width: 100%;\n\n\twidth: var(--base-width);\n\n\t&.xs {\n\t\t--base-width: calc(var(--drp-ui-width-xs, var(--ui-width-xs)) - var(--width-add));\n\t}\n\n\t&.sm {\n\t\t--base-width: calc(var(--drp-ui-width-sm, var(--ui-width-sm)) - var(--width-add));\n\t}\n\n\t&.md {\n\t\t--base-width: calc(var(--drp-ui-width-md, var(--ui-width-md)) - var(--width-add));\n\t}\n\n\t&.lg {\n\t\t--base-width: calc(var(--drp-ui-width-lg, var(--ui-width-lg)) - var(--width-add));\n\t}\n\n\t&.xl {\n\t\t--base-width: calc(var(--drp-ui-width-xl, var(--ui-width-xl)) - var(--width-add));\n\t}\n}\n\n// TODO: Тестовый класс\n.uiErrorElement {\n\t--grid-size: var(--space-sm);\n\t--grid-line-size: var(--border-width);\n\t--grid-line-color: color-mix(in srgb, var(--error-fill) 12%, var(--surface-0));\n\n\theight: var(--control-height);\n\twidth: 100%; // calc(10em - var(--width-add));\n\tflex-shrink: 0;\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\n\tborder: var(--focus-width) solid var(--error-border);\n\tborder-radius: var(--radius-sm);\n\toutline: none;\n\n\tfont-weight: 700;\n\tfont-variation-settings: \"wght\" 700;\n\n\tcolor: var(--error-text);\n\tbackground-color: var(--surface-0);\n\tbackground-image:\n\t\trepeating-linear-gradient(\n\t\t\t45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t),\n\t\trepeating-linear-gradient(\n\t\t\t-45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t);\n}\n\n.uiContainer {\n\tposition: relative;\n\twidth: 100%;\n}\n\n.uiInputContainer {\n\t@extend .uiContainer;\n\n\t--padding-right: var(--control-height);\n}\n\n.uiLabelBase {\n\tdisplay: inline-block;\n\tfont-weight: 400;\n\tfont-variation-settings: \"wght\" 400;\n}\n\n.uiLabel {\n\t@extend .uiLabelBase;\n\n\tmargin-block: var(--space-xs);\n}\n\n.uiDescription {\n\t--paragraph-margin: 0;\n\n\tpadding-bottom: var(--space-xs);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiLabel,\n.uiDescription {\n\tmargin-inline: var(--space-xs);\n}\n\n.uiPlaceholder {\n\tcolor: var(--content-2);\n\tfont-weight: 100;\n\tfont-variation-settings: \"wght\" 100;\n\t// font-size: var(--font-size-sm);\n\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.required {\n\t.uiLabelBase::after {\n\t\tcontent: \" *\";\n\t\tcolor: var(--error-text);\n\t}\n}\n\n.uiControl {\n\t@include ui-tone(\"neutral\");\n\t@include ui-appearance-outline;\n\t@include ui-control-base;\n\n\t--ui-radius: var(--radius-sm);\n\n\t&.invalid,\n\t&:invalid {\n\t\t@include ui-tone(\"error\");\n\t\t@include ui-appearance-outline;\n\t}\n\n\t&::placeholder {\n\t\t@extend .uiPlaceholder;\n\t}\n}\n\n.uiToneNeutral {\n\t@include ui-tone(\"neutral\");\n}\n\n.uiToneAccent {\n\t@include ui-tone(\"accent\");\n}\n\n.uiToneBrand {\n\t@include ui-tone(\"brand\");\n}\n\n.uiToneError {\n\t@include ui-tone(\"error\");\n}\n\n.uiToneWarning {\n\t@include ui-tone(\"warning\");\n}\n\n.uiToneSuccess {\n\t@include ui-tone(\"success\");\n}\n\n.uiToneInfo {\n\t@include ui-tone(\"info\");\n}\n\n.uiAppearanceSolid {\n\t@include ui-appearance-solid;\n}\n\n.uiAppearanceOutline {\n\t@include ui-appearance-outline;\n}\n\n.uiAppearanceGhost {\n\t@include ui-appearance-ghost;\n}\n\n.uiAppearanceTransparent {\n\t@include ui-appearance-transparent;\n}\n\n.uiInputControl {\n\t@extend .uiControl;\n\n\theight: var(--control-height);\n}\n\n.uiInputWithToggle {\n\t@extend .uiInputControl;\n\n\tcolor: var(--content-0);\n\n\tpadding: 0 var(--padding-right) 0 var(--space-sm);\n\twidth: 100%;\n\ttext-align: left;\n\n\t// &[type=\"button\"] {\n\t// \twhite-space: nowrap;\n\t// }\n}\n\n.uiSelectionControl {\n\t@include ui-control-base;\n\n\t--ui-color: var(--content-0);\n\t--ui-color-hover: var(--content-0);\n\t--ui-color-active: var(--content-0);\n\t--ui-background: var(--surface-0);\n\t--ui-background-hover: var(--ui-tone-soft);\n\t--ui-background-active: var(--ui-tone-soft);\n\t--ui-border-color: var(--ui-tone-border);\n\t--ui-border-hover: var(--ui-tone-border-hover);\n\t--ui-border-active: var(--ui-tone-border-active);\n\t--ui-border-focus: var(--ui-tone-border-focus);\n\n\tappearance: none;\n\tmargin: 0;\n\tcursor: pointer;\n\n\t&:checked {\n\t\tborder-color: var(--ui-tone-border-active);\n\n\t\t& + .uiSelectionIcon {\n\t\t\tcolor: var(--ui-tone-fill);\n\t\t}\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\n\t\tborder-color: var(--border-0);\n\n\t\t&:checked {\n\t\t\t& + .uiSelectionIcon {\n\t\t\t\tcolor: var(--border-0);\n\t\t\t}\n\t\t}\n\t}\n}\n\n.uiSelectionIcon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%);\n\tpointer-events: none;\n\tcolor: transparent;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\topacity var(--transition-fast) ease;\n}\n\n.uiElement,\n.uiPopupOption {\n\t&.disabled,\n\t&:disabled {\n\t\tuser-select: none;\n\n\t\t.uiLabel,\n\t\t.uiDescription {\n\t\t\tcolor: var(--content-2);\n\t\t}\n\n\t\t.uiPlaceholder,\n\t\t.uiOptionText,\n\t\t.uiOptionCode {\n\t\t\topacity: 0.25;\n\t\t}\n\t}\n\n\t// Класс disabled используется у составных ненативных элементов: им нужно явно запретить события.\n\t&.disabled {\n\t\tcursor: default;\n\t\tpointer-events: none;\n\t}\n\n\t// Нативный disabled уже блокирует активацию, а pointer-events остаются для курсора и tooltip.\n\t&:disabled {\n\t\tcursor: not-allowed;\n\t}\n}\n\n.uiPanelTonePrimary {\n\t--ui-panel-background: var(--surface-0);\n}\n\n.uiPanelToneSecondary {\n\t--ui-panel-background: var(--surface-1);\n}\n\n.uiPanelToneTertiary {\n\t--ui-panel-background: var(--surface-2);\n}\n\n.uiFilledPanel {\n\tbackground-color: var(--ui-panel-background, var(--surface-0));\n}\n\n.uiFramedPanel {\n\tborder: var(--border);\n\tborder-radius: var(--radius-sm);\n\tpadding: var(--space-sm);\n}\n\n.uiPanel {\n\t@extend .uiFramedPanel;\n\t@extend .uiFilledPanel;\n}\n\n.uiStateFocus {\n\t@include focusVisible;\n\n\tbackground-color: var(--surface-1);\n\tborder-color: var(--border-1);\n\tcursor: pointer;\n}\n\n.uiOptionBase {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tgap: var(--space-sm);\n\theight: 100%;\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.uiPopupOption {\n\t@extend .uiOptionBase;\n\n\theight: auto;\n\tmin-height: var(--control-height);\n}\n\n.uiPopupOption {\n\tborder-radius: var(--radius-sm);\n\tborder: none;\n\tbackground-color: transparent;\n\tcolor: var(--content-0);\n\n\ttransition:\n\t\tbackground-color var(--transition-fast) ease,\n\t\tcolor var(--transition-fast) ease;\n\n\t.uiMenuOptionIcon,\n\t.uiPopupOptionIcon {\n\t\tflex-shrink: 0;\n\t\tfont-size: var(--font-size-sm);\n\t\twidth: var(--icon-size);\n\t\theight: var(--icon-size);\n\t}\n\n\t.uiMenuOptionIcon,\n\t.keyboard {\n\t\tcolor: var(--content-2);\n\t}\n\n\t&.selected {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t\tcursor: default;\n\t}\n\n\t&.uiPopupOptionActive,\n\t&:active {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t}\n\n\t@include hover(true) {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t\tcursor: pointer;\n\t}\n\n\t&.disabled {\n\t\t// background-color: var(--surface-2);\n\t\tcolor: var(--content-2);\n\t}\n\n\t&:focus-within {\n\t\t// @extend .uiStateFocus;\n\t\t@include focusVisible;\n\t}\n}\n\n.uiOptionButton,\n.uiOptionLink {\n\t@extend .uiOptionBase;\n\n\tflex: 1 1 0;\n\tmin-width: 0;\n\theight: 100%;\n\tpadding: var(--space-xs) var(--space-sm);\n\tborder: none;\n\tborder-radius: inherit;\n\toutline: none;\n\tbackground: transparent;\n\tcolor: inherit;\n\tcursor: inherit;\n\ttext-decoration: none;\n}\n\n.uiPopupOptionSeparator {\n\tborder-top: var(--border);\n\tmargin-block: var(--space-xs);\n}\n\n.uiPopupGroupLabel {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n\tfont-weight: 300;\n\ttext-transform: uppercase;\n\tfont-size: var(--font-size-sm);\n}\n\n.uiMenuOptionIcon {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.uiOptionText {\n\t// font-size: var(--font-size-sm);\n\tflex: 1;\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.uiOptionCode {\n\tfont-family: var(--font-family-mono);\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiOptionContentEmphasize {\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.uiToggleButtonContainer {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\theight: 100%;\n\twidth: 100%;\n\n\ttransition-property: width;\n\ttransition-duration: var(--transition-fast);\n\ttransition-timing-function: cubic-bezier(1, 0, 0.5, 0.5);\n\n\t> button {\n\t\tbackground: transparent;\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: var(--control-height);\n\t\twidth: var(--control-height);\n\t\tborder-radius: var(--radius-sm);\n\t\tflex: 0 0 var(--control-height);\n\t}\n\n\t// &[data-disabled] {\n\t// \tcursor: default;\n\t// \tpointer-events: none;\n\t// \topacity: var(--disabled-opacity);\n\t// }\n}\n\n.uiToggleButton {\n\tcolor: var(--content-0);\n\n\t&:hover {\n\t\tcolor: var(--accent-text);\n\t}\n}\n\n.uiToggleIcon {\n\ttransition: transform var(--transition-fast) ease-in-out;\n\n\t&.uiToggleIconOpen {\n\t\ttransform: rotate(180deg);\n\t}\n}\n\n// TODO: пока в свалку стили для дата-подобных компонентов\n\n// Для компонентов, который не являются input, но выставляют себя за него\n.uiInputControlFake {\n\t@extend .uiInputControl;\n\n\twidth: 100%;\n\tpadding: 0 var(--space-sm);\n\tfont-size: var(--font-size-md);\n\n\tdisplay: flex;\n\talign-items: center;\n\n\tcursor: text;\n}\n\n.uiClearButton {\n\tcolor: var(--error-text);\n\n\t&:disabled {\n\t\topacity: 0;\n\t\tpointer-events: none;\n\t\twidth: 0;\n\t\theight: 0;\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t\toverflow: hidden;\n\t}\n}\n\n.uiButtonSeparator {\n\tborder-left: var(--border);\n\theight: calc(100% - var(--space-sm));\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ui.module-oRwY3Zli.js","names":[],"sources":["../../src/ui.module.scss"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n@use \"@/styles/tone-derived\" as toneDerived;\n\n.uiSizable {\n\t--base-width: 100%;\n\n\twidth: var(--base-width);\n\n\t&.xs {\n\t\t--base-width: calc(var(--drp-ui-width-xs, var(--ui-width-xs)) - var(--width-add));\n\t}\n\n\t&.sm {\n\t\t--base-width: calc(var(--drp-ui-width-sm, var(--ui-width-sm)) - var(--width-add));\n\t}\n\n\t&.md {\n\t\t--base-width: calc(var(--drp-ui-width-md, var(--ui-width-md)) - var(--width-add));\n\t}\n\n\t&.lg {\n\t\t--base-width: calc(var(--drp-ui-width-lg, var(--ui-width-lg)) - var(--width-add));\n\t}\n\n\t&.xl {\n\t\t--base-width: calc(var(--drp-ui-width-xl, var(--ui-width-xl)) - var(--width-add));\n\t}\n}\n\n// TODO: Тестовый класс\n.uiErrorElement {\n\t--grid-size: var(--space-sm);\n\t--grid-line-size: var(--border-width);\n\t@include toneDerived.tone-soft-declaration(\"--grid-line-color\", \"error\");\n\n\theight: var(--control-height);\n\twidth: 100%; // calc(10em - var(--width-add));\n\tflex-shrink: 0;\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\n\tborder: var(--focus-width) solid var(--error-border);\n\tborder-radius: var(--radius-sm);\n\toutline: none;\n\n\tfont-weight: 700;\n\tfont-variation-settings: \"wght\" 700;\n\n\tcolor: var(--error-text);\n\tbackground-color: var(--surface-0);\n\tbackground-image:\n\t\trepeating-linear-gradient(\n\t\t\t45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t),\n\t\trepeating-linear-gradient(\n\t\t\t-45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t);\n}\n\n.uiContainer {\n\tposition: relative;\n\twidth: 100%;\n}\n\n.uiInputContainer {\n\t@extend .uiContainer;\n\n\t--padding-right: var(--control-height);\n}\n\n.uiLabelBase {\n\tdisplay: inline-block;\n\tfont-weight: 400;\n\tfont-variation-settings: \"wght\" 400;\n}\n\n.uiLabel {\n\t@extend .uiLabelBase;\n\n\tmargin-block: var(--space-xs);\n}\n\n.uiDescription {\n\t--paragraph-margin: 0;\n\n\tpadding-bottom: var(--space-xs);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiLabel,\n.uiDescription {\n\tmargin-inline: var(--space-xs);\n}\n\n.uiPlaceholder {\n\tcolor: var(--content-2);\n\tfont-weight: 100;\n\tfont-variation-settings: \"wght\" 100;\n\t// font-size: var(--font-size-sm);\n\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.required {\n\t.uiLabelBase::after {\n\t\tcontent: \" *\";\n\t\tcolor: var(--error-text);\n\t}\n}\n\n.uiControl {\n\t@include ui-tone(\"neutral\");\n\t@include ui-appearance-outline;\n\t@include ui-control-base;\n\n\t--ui-radius: var(--radius-sm);\n\n\t&.invalid,\n\t&:invalid {\n\t\t@include ui-tone(\"error\");\n\t\t@include ui-appearance-outline;\n\t}\n\n\t&::placeholder {\n\t\t@extend .uiPlaceholder;\n\t}\n}\n\n.uiToneNeutral {\n\t@include ui-tone(\"neutral\");\n}\n\n.uiToneAccent {\n\t@include ui-tone(\"accent\");\n}\n\n.uiToneBrand {\n\t@include ui-tone(\"brand\");\n}\n\n.uiToneError {\n\t@include ui-tone(\"error\");\n}\n\n.uiToneWarning {\n\t@include ui-tone(\"warning\");\n}\n\n.uiToneSuccess {\n\t@include ui-tone(\"success\");\n}\n\n.uiToneInfo {\n\t@include ui-tone(\"info\");\n}\n\n.uiAppearanceSolid {\n\t@include ui-appearance-solid;\n}\n\n.uiAppearanceOutline {\n\t@include ui-appearance-outline;\n}\n\n.uiAppearanceGhost {\n\t@include ui-appearance-ghost;\n}\n\n.uiAppearanceTransparent {\n\t@include ui-appearance-transparent;\n}\n\n.uiInputControl {\n\t@extend .uiControl;\n\n\theight: var(--control-height);\n}\n\n.uiInputWithToggle {\n\t@extend .uiInputControl;\n\n\tcolor: var(--content-0);\n\n\tpadding: 0 var(--padding-right) 0 var(--space-sm);\n\twidth: 100%;\n\ttext-align: left;\n\n\t// &[type=\"button\"] {\n\t// \twhite-space: nowrap;\n\t// }\n}\n\n.uiSelectionControl {\n\t@include ui-control-base;\n\n\t--ui-color: var(--content-0);\n\t--ui-color-hover: var(--content-0);\n\t--ui-color-active: var(--content-0);\n\t--ui-background: var(--surface-0);\n\t--ui-background-hover: var(--ui-tone-soft);\n\t--ui-background-active: var(--ui-tone-soft);\n\t--ui-border-color: var(--ui-tone-border);\n\t--ui-border-hover: var(--ui-tone-border-hover);\n\t--ui-border-active: var(--ui-tone-border-active);\n\t--ui-border-focus: var(--ui-tone-border-focus);\n\n\tappearance: none;\n\tmargin: 0;\n\tcursor: pointer;\n\n\t&:checked {\n\t\tborder-color: var(--ui-tone-border-active);\n\n\t\t& + .uiSelectionIcon {\n\t\t\tcolor: var(--ui-tone-fill);\n\t\t}\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\n\t\tborder-color: var(--border-0);\n\n\t\t&:checked {\n\t\t\t& + .uiSelectionIcon {\n\t\t\t\tcolor: var(--border-0);\n\t\t\t}\n\t\t}\n\t}\n}\n\n.uiSelectionIcon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%);\n\tpointer-events: none;\n\tcolor: transparent;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\topacity var(--transition-fast) ease;\n}\n\n.uiElement,\n.uiPopupOption {\n\t&.disabled,\n\t&:disabled {\n\t\tuser-select: none;\n\n\t\t.uiLabel,\n\t\t.uiDescription {\n\t\t\tcolor: var(--content-2);\n\t\t}\n\n\t\t.uiPlaceholder,\n\t\t.uiOptionText,\n\t\t.uiOptionCode {\n\t\t\topacity: 0.25;\n\t\t}\n\t}\n\n\t// Класс disabled используется у составных ненативных элементов: им нужно явно запретить события.\n\t&.disabled {\n\t\tcursor: default;\n\t\tpointer-events: none;\n\t}\n\n\t// Нативный disabled уже блокирует активацию, а pointer-events остаются для курсора и tooltip.\n\t&:disabled {\n\t\tcursor: not-allowed;\n\t}\n}\n\n.uiPanelTonePrimary {\n\t--ui-panel-background: var(--surface-0);\n}\n\n.uiPanelToneSecondary {\n\t--ui-panel-background: var(--surface-1);\n}\n\n.uiPanelToneTertiary {\n\t--ui-panel-background: var(--surface-2);\n}\n\n.uiFilledPanel {\n\tbackground-color: var(--ui-panel-background, var(--surface-0));\n}\n\n.uiFramedPanel {\n\tborder: var(--border);\n\tborder-radius: var(--radius-sm);\n\tpadding: var(--space-sm);\n}\n\n.uiPanel {\n\t@extend .uiFramedPanel;\n\t@extend .uiFilledPanel;\n}\n\n.uiStateFocus {\n\t@include focusVisible;\n\n\tbackground-color: var(--surface-1);\n\tborder-color: var(--border-1);\n\tcursor: pointer;\n}\n\n.uiOptionBase {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tgap: var(--space-sm);\n\theight: 100%;\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.uiPopupOption {\n\t@extend .uiOptionBase;\n\n\theight: auto;\n\tmin-height: var(--control-height);\n}\n\n.uiPopupOption {\n\tborder-radius: var(--radius-sm);\n\tborder: none;\n\tbackground-color: transparent;\n\tcolor: var(--content-0);\n\n\ttransition:\n\t\tbackground-color var(--transition-fast) ease,\n\t\tcolor var(--transition-fast) ease;\n\n\t.uiMenuOptionIcon,\n\t.uiPopupOptionIcon {\n\t\tflex-shrink: 0;\n\t\tfont-size: var(--font-size-sm);\n\t\twidth: var(--icon-size);\n\t\theight: var(--icon-size);\n\t}\n\n\t.uiMenuOptionIcon,\n\t.keyboard {\n\t\tcolor: var(--content-2);\n\t}\n\n\t&.selected {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t\tcursor: default;\n\t}\n\n\t@include hover(true, false) {\n\t\tcolor: var(--accent-text-hover);\n\t\tbackground-color: var(--accent-fill-hover);\n\t\tcursor: pointer;\n\t}\n\n\t// Active идёт после hover, чтобы нажатие не теряло своё состояние у мыши и touch-устройств.\n\t&.uiPopupOptionActive,\n\t&:active {\n\t\tcolor: var(--accent-text-active);\n\t\tbackground-color: var(--accent-fill-active);\n\t}\n\n\t&.disabled {\n\t\t// background-color: var(--surface-2);\n\t\tcolor: var(--content-2);\n\t}\n\n\t&:focus-within {\n\t\t// @extend .uiStateFocus;\n\t\t@include focusVisible;\n\t}\n}\n\n.uiOptionButton,\n.uiOptionLink {\n\t@extend .uiOptionBase;\n\n\tflex: 1 1 0;\n\tmin-width: 0;\n\theight: 100%;\n\tpadding: var(--space-xs) var(--space-sm);\n\tborder: none;\n\tborder-radius: inherit;\n\toutline: none;\n\tbackground: transparent;\n\tcolor: inherit;\n\tcursor: inherit;\n\ttext-decoration: none;\n}\n\n.uiPopupOptionSeparator {\n\tborder-top: var(--border);\n\tmargin-block: var(--space-xs);\n}\n\n.uiPopupGroupLabel {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n\tfont-weight: 300;\n\ttext-transform: uppercase;\n\tfont-size: var(--font-size-sm);\n}\n\n.uiMenuOptionIcon {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.uiOptionText {\n\t// font-size: var(--font-size-sm);\n\tflex: 1;\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.uiOptionCode {\n\tfont-family: var(--font-family-mono);\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiOptionContentEmphasize {\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.uiToggleButtonContainer {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\theight: 100%;\n\twidth: 100%;\n\n\ttransition-property: width;\n\ttransition-duration: var(--transition-fast);\n\ttransition-timing-function: cubic-bezier(1, 0, 0.5, 0.5);\n\n\t> button {\n\t\tbackground: transparent;\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: var(--control-height);\n\t\twidth: var(--control-height);\n\t\tborder-radius: var(--radius-sm);\n\t\tflex: 0 0 var(--control-height);\n\t}\n\n\t// &[data-disabled] {\n\t// \tcursor: default;\n\t// \tpointer-events: none;\n\t// \topacity: var(--disabled-opacity);\n\t// }\n}\n\n.uiToggleButton {\n\tcolor: var(--content-0);\n\n\t&:hover {\n\t\tcolor: var(--accent-text);\n\t}\n}\n\n.uiToggleIcon {\n\ttransition: transform var(--transition-fast) ease-in-out;\n\n\t&.uiToggleIconOpen {\n\t\ttransform: rotate(180deg);\n\t}\n}\n\n// TODO: пока в свалку стили для дата-подобных компонентов\n\n// Для компонентов, который не являются input, но выставляют себя за него\n.uiInputControlFake {\n\t@extend .uiInputControl;\n\n\twidth: 100%;\n\tpadding: 0 var(--space-sm);\n\tfont-size: var(--font-size-md);\n\n\tdisplay: flex;\n\talign-items: center;\n\n\tcursor: text;\n}\n\n.uiClearButton {\n\tcolor: var(--error-text);\n\n\t&:disabled {\n\t\topacity: 0;\n\t\tpointer-events: none;\n\t\twidth: 0;\n\t\theight: 0;\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t\toverflow: hidden;\n\t}\n}\n\n.uiButtonSeparator {\n\tborder-left: var(--border);\n\theight: calc(100% - var(--space-sm));\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/notifications/model/NotificationsProvider.tsx","../../src/notifications/ui/Notification.module.scss","../../src/notifications/ui/NotificationsHost.tsx"],"sourcesContent":["/* eslint-disable react-refresh/only-export-components */\nimport { createContext, PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\n\nimport { createMissingContextError } from \"@ryuzaki13/react-foundation-lib/error\";\nimport {\n\tbindNotifications,\n\tcreateNotificationsStore,\n\tNotificationId,\n\tNotificationPushInput,\n\tNotificationsStoreApi,\n\tNotificationType\n} from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { useStore } from \"zustand\";\n\nconst NotificationsContext = createContext<NotificationsStoreApi | null>(null);\n\n/**\n * Провайдер уведомлений приложения. Хранит состояние списка уведомлений и предоставляет хуки доступа к нему.\n */\nexport function NotificationsProvider({ children }: PropsWithChildren) {\n\tconst store = useMemo(() => createNotificationsStore(), []);\n\n\tuseEffect(() => {\n\t\treturn bindNotifications(store);\n\t}, [store]);\n\n\treturn <NotificationsContext.Provider value={store}>{children}</NotificationsContext.Provider>;\n}\n\nfunction useNotificationApi() {\n\tconst ctx = useContext(NotificationsContext);\n\tif (!ctx) {\n\t\tthrow createMissingContextError({\n\t\t\thookName: \"useNotificationApi\",\n\t\t\tproviderName: \"NotificationsProvider\"\n\t\t});\n\t}\n\treturn ctx;\n}\n\nexport function useNotifications() {\n\tconst api = useNotificationApi();\n\treturn useStore(api, (s) => s.items);\n}\n\nexport function useNotify() {\n\tconst api = useNotificationApi();\n\tconst actions = useStore(api, (s) => s.actions);\n\n\tconst mk = (type: NotificationType) => (message: string, opts?: Omit<NotificationPushInput, \"type\" | \"message\">) =>\n\t\tactions.push({ type, message, ...opts });\n\n\treturn {\n\t\t...actions,\n\t\tsuccess: mk(\"success\"),\n\t\tinfo: mk(\"info\"),\n\t\twarning: mk(\"warning\"),\n\t\terror: mk(\"error\")\n\t};\n}\n\nexport function useNotificationById(id: NotificationId) {\n\tconst api = useNotificationApi();\n\treturn useStore(api, (s) => s.items.find((n) => n.id === id));\n}\n","@use \"@/styles/mixins\" as *;\n\n.container {\n\tposition: fixed;\n\tz-index: var(--z-notify);\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: grid;\n\tgap: var(--space-sm);\n\tpadding: var(--space-lg);\n\twidth: min(28em, calc(100dvw - var(--space-lg) * 2));\n\tpointer-events: none;\n}\n\n.card {\n\t--notify-accent: var(--border-1);\n\t--notify-accent-surface: var(--surface-1);\n\t--notify-accent-text: var(--accent-text);\n\n\tposition: relative;\n\toverflow: hidden;\n\tpointer-events: auto;\n\twidth: 100%;\n\tpadding: var(--space-md);\n\t// border: var(--border);\n\tborder-left: 0.3125em solid var(--notify-accent);\n\tborder-radius: var(--radius-md);\n\tbackground: linear-gradient(37deg, var(--notify-accent-surface), var(--surface-0));\n\tcolor: var(--content-0);\n\tbox-shadow: var(--shadow-md);\n}\n\n.info {\n\t--notify-accent: var(--info-border);\n\t--notify-accent-surface: color-mix(in srgb, var(--info-fill) 12%, var(--surface-0));\n\t--notify-accent-text: var(--info-text);\n}\n\n.success {\n\t--notify-accent: var(--success-border);\n\t--notify-accent-surface: color-mix(in srgb, var(--success-fill) 12%, var(--surface-0));\n\t--notify-accent-text: var(--success-text);\n}\n\n.warning {\n\t--notify-accent: var(--warning-border);\n\t--notify-accent-surface: color-mix(in srgb, var(--warning-fill) 12%, var(--surface-0));\n\t--notify-accent-text: var(--warning-text);\n}\n\n.error {\n\t--notify-accent: var(--error-border);\n\t--notify-accent-surface: color-mix(in srgb, var(--error-fill) 12%, var(--surface-0));\n\t--notify-accent-text: var(--error-text);\n}\n\n.header,\n.content,\n.copy {\n\tmin-width: 0;\n}\n\n.content {\n\tmin-width: 0;\n\tflex: 1;\n}\n\n.icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: var(--control-height);\n\theight: var(--control-height);\n\tborder-radius: 50%;\n\tbackground-color: var(--notify-accent-surface);\n\tcolor: var(--notify-accent-text);\n\tborder: var(--border-width) solid color-mix(in srgb, var(--notify-accent) 22%, transparent);\n\n\tsvg {\n\t\twidth: 1.125em;\n\t\theight: 1.125em;\n\t}\n}\n\n.kicker {\n\tmargin-bottom: var(--space-xs);\n\tcolor: var(--notify-accent-text);\n\tfont-size: var(--font-size-xs);\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n\tletter-spacing: 0.04em;\n\ttext-transform: uppercase;\n}\n\n.title {\n\tcolor: var(--notify-accent-text);\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.message {\n\tmargin-top: var(--space-xs);\n\tcolor: var(--content-0);\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n}\n\n.actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--space-xs);\n\tmargin-top: var(--space-sm);\n}\n\n@include mobile {\n\t.container {\n\t\tpadding: var(--space-md);\n\t\twidth: min(100dvw, calc(100dvw - var(--space-md) * 2));\n\t}\n}\n","import { NotificationType } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { AlertCircleIcon, CheckCircle2Icon, InfoIcon, TriangleAlertIcon, XIcon } from \"lucide-react\";\n\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { useNotifications, useNotify } from \"../model/NotificationsProvider\";\n\nimport styles from \"./Notification.module.scss\";\n\nconst notificationConfig: Record<\n\tNotificationType,\n\t{\n\t\ttitle: string;\n\t\tIcon: typeof InfoIcon;\n\t}\n> = {\n\tinfo: {\n\t\ttitle: \"Информация\",\n\t\tIcon: InfoIcon\n\t},\n\tsuccess: {\n\t\ttitle: \"Успешно\",\n\t\tIcon: CheckCircle2Icon\n\t},\n\twarning: {\n\t\ttitle: \"Предупреждение\",\n\t\tIcon: TriangleAlertIcon\n\t},\n\terror: {\n\t\ttitle: \"Ошибка\",\n\t\tIcon: AlertCircleIcon\n\t}\n};\n\n/**\n * Хост для визуального отображения очереди уведомлений.\n * Обычно монтируется один раз на уровне приложения рядом с провайдером уведомлений.\n */\nexport function NotificationsHost() {\n\tconst items = useNotifications();\n\tconst { dismiss } = useNotify();\n\n\treturn (\n\t\t<div className={styles.container} aria-label=\"Область уведомлений\" aria-live=\"polite\" aria-relevant=\"additions text\">\n\t\t\t{items.map((notification) => {\n\t\t\t\tconst config = notificationConfig[notification.type];\n\t\t\t\tconst title = notification.title ?? config.title;\n\t\t\t\tconst Icon = config.Icon;\n\n\t\t\t\treturn (\n\t\t\t\t\t<article\n\t\t\t\t\t\tkey={notification.id}\n\t\t\t\t\t\trole={notification.type === \"error\" ? \"alert\" : \"status\"}\n\t\t\t\t\t\taria-atomic=\"true\"\n\t\t\t\t\t\tclassName={cn(styles.card, styles[notification.type])}>\n\t\t\t\t\t\t<FlexContainer align=\"start\" justify=\"between\" gap=\"sm\" className={styles.header}>\n\t\t\t\t\t\t\t<FlexContainer align=\"start\" gap=\"sm\" className={styles.content}>\n\t\t\t\t\t\t\t\t<span className={styles.icon} aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t<Icon />\n\t\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t\t<div className={styles.copy}>\n\t\t\t\t\t\t\t\t\t<div className={styles.kicker}>{config.title}</div>\n\t\t\t\t\t\t\t\t\t{notification.title ? <div className={styles.title}>{title}</div> : null}\n\t\t\t\t\t\t\t\t\t<div className={styles.message}>{notification.message}</div>\n\n\t\t\t\t\t\t\t\t\t{notification.actions?.length ? (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.actions}>\n\t\t\t\t\t\t\t\t\t\t\t{notification.actions.map((action) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={action.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\ttone={action.tone ?? notification.type}\n\t\t\t\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-ui=\"notification-action-button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-action=\"notification-action\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => void action.onClick()}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</FlexContainer>\n\n\t\t\t\t\t\t\t{notification.dismissible !== false ? (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ticon={<XIcon />}\n\t\t\t\t\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\t\t\t\t\ttone={notification.type}\n\t\t\t\t\t\t\t\t\tonClick={() => dismiss(notification.id)}\n\t\t\t\t\t\t\t\t\taria-label=\"Закрыть уведомление\"\n\t\t\t\t\t\t\t\t\tdata-ui=\"notification-dismiss-button\"\n\t\t\t\t\t\t\t\t\tdata-action=\"dismiss-notification\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t</article>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/notifications/model/NotificationsProvider.tsx","../../src/notifications/ui/Notification.module.scss","../../src/notifications/ui/NotificationsHost.tsx"],"sourcesContent":["/* eslint-disable react-refresh/only-export-components */\nimport { createContext, PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\n\nimport { createMissingContextError } from \"@ryuzaki13/react-foundation-lib/error\";\nimport {\n\tbindNotifications,\n\tcreateNotificationsStore,\n\tNotificationId,\n\tNotificationPushInput,\n\tNotificationsStoreApi,\n\tNotificationType\n} from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { useStore } from \"zustand\";\n\nconst NotificationsContext = createContext<NotificationsStoreApi | null>(null);\n\n/**\n * Провайдер уведомлений приложения. Хранит состояние списка уведомлений и предоставляет хуки доступа к нему.\n */\nexport function NotificationsProvider({ children }: PropsWithChildren) {\n\tconst store = useMemo(() => createNotificationsStore(), []);\n\n\tuseEffect(() => {\n\t\treturn bindNotifications(store);\n\t}, [store]);\n\n\treturn <NotificationsContext.Provider value={store}>{children}</NotificationsContext.Provider>;\n}\n\nfunction useNotificationApi() {\n\tconst ctx = useContext(NotificationsContext);\n\tif (!ctx) {\n\t\tthrow createMissingContextError({\n\t\t\thookName: \"useNotificationApi\",\n\t\t\tproviderName: \"NotificationsProvider\"\n\t\t});\n\t}\n\treturn ctx;\n}\n\nexport function useNotifications() {\n\tconst api = useNotificationApi();\n\treturn useStore(api, (s) => s.items);\n}\n\nexport function useNotify() {\n\tconst api = useNotificationApi();\n\tconst actions = useStore(api, (s) => s.actions);\n\n\tconst mk = (type: NotificationType) => (message: string, opts?: Omit<NotificationPushInput, \"type\" | \"message\">) =>\n\t\tactions.push({ type, message, ...opts });\n\n\treturn {\n\t\t...actions,\n\t\tsuccess: mk(\"success\"),\n\t\tinfo: mk(\"info\"),\n\t\twarning: mk(\"warning\"),\n\t\terror: mk(\"error\")\n\t};\n}\n\nexport function useNotificationById(id: NotificationId) {\n\tconst api = useNotificationApi();\n\treturn useStore(api, (s) => s.items.find((n) => n.id === id));\n}\n","@use \"@/styles/mixins\" as *;\n@use \"@/styles/tone-derived\" as toneDerived;\n\n.container {\n\tposition: fixed;\n\tz-index: var(--z-notify);\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: grid;\n\tgap: var(--space-sm);\n\tpadding: var(--space-lg);\n\twidth: min(28em, calc(100dvw - var(--space-lg) * 2));\n\tpointer-events: none;\n}\n\n.card {\n\t--notify-accent: var(--border-1);\n\t--notify-accent-surface: var(--surface-1);\n\t--notify-accent-text: var(--accent-text);\n\n\tposition: relative;\n\toverflow: hidden;\n\tpointer-events: auto;\n\twidth: 100%;\n\tpadding: var(--space-md);\n\t// border: var(--border);\n\tborder-left: 0.3125em solid var(--notify-accent);\n\tborder-radius: var(--radius-md);\n\tbackground: linear-gradient(37deg, var(--notify-accent-surface), var(--surface-0));\n\tcolor: var(--content-0);\n\tbox-shadow: var(--shadow-md);\n}\n\n.info {\n\t--notify-accent: var(--info-border);\n\t@include toneDerived.tone-soft-declaration(\"--notify-accent-surface\", \"info\");\n\t--notify-accent-text: var(--info-text);\n}\n\n.success {\n\t--notify-accent: var(--success-border);\n\t@include toneDerived.tone-soft-declaration(\"--notify-accent-surface\", \"success\");\n\t--notify-accent-text: var(--success-text);\n}\n\n.warning {\n\t--notify-accent: var(--warning-border);\n\t@include toneDerived.tone-soft-declaration(\"--notify-accent-surface\", \"warning\");\n\t--notify-accent-text: var(--warning-text);\n}\n\n.error {\n\t--notify-accent: var(--error-border);\n\t@include toneDerived.tone-soft-declaration(\"--notify-accent-surface\", \"error\");\n\t--notify-accent-text: var(--error-text);\n}\n\n.header,\n.content,\n.copy {\n\tmin-width: 0;\n}\n\n.content {\n\tmin-width: 0;\n\tflex: 1;\n}\n\n.icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n\twidth: var(--control-height);\n\theight: var(--control-height);\n\tborder-radius: 50%;\n\tbackground-color: var(--notify-accent-surface);\n\tcolor: var(--notify-accent-text);\n\tborder: var(--border-width) solid color-mix(in srgb, var(--notify-accent) 22%, transparent);\n\n\tsvg {\n\t\twidth: 1.125em;\n\t\theight: 1.125em;\n\t}\n}\n\n.kicker {\n\tmargin-bottom: var(--space-xs);\n\tcolor: var(--notify-accent-text);\n\tfont-size: var(--font-size-xs);\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n\tletter-spacing: 0.04em;\n\ttext-transform: uppercase;\n}\n\n.title {\n\tcolor: var(--notify-accent-text);\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.message {\n\tmargin-top: var(--space-xs);\n\tcolor: var(--content-0);\n\twhite-space: pre-wrap;\n\tword-break: break-word;\n}\n\n.actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--space-xs);\n\tmargin-top: var(--space-sm);\n}\n\n@include mobile {\n\t.container {\n\t\tpadding: var(--space-md);\n\t\twidth: min(100dvw, calc(100dvw - var(--space-md) * 2));\n\t}\n}\n","import { NotificationType } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { AlertCircleIcon, CheckCircle2Icon, InfoIcon, TriangleAlertIcon, XIcon } from \"lucide-react\";\n\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { useNotifications, useNotify } from \"../model/NotificationsProvider\";\n\nimport styles from \"./Notification.module.scss\";\n\nconst notificationConfig: Record<\n\tNotificationType,\n\t{\n\t\ttitle: string;\n\t\tIcon: typeof InfoIcon;\n\t}\n> = {\n\tinfo: {\n\t\ttitle: \"Информация\",\n\t\tIcon: InfoIcon\n\t},\n\tsuccess: {\n\t\ttitle: \"Успешно\",\n\t\tIcon: CheckCircle2Icon\n\t},\n\twarning: {\n\t\ttitle: \"Предупреждение\",\n\t\tIcon: TriangleAlertIcon\n\t},\n\terror: {\n\t\ttitle: \"Ошибка\",\n\t\tIcon: AlertCircleIcon\n\t}\n};\n\n/**\n * Хост для визуального отображения очереди уведомлений.\n * Обычно монтируется один раз на уровне приложения рядом с провайдером уведомлений.\n */\nexport function NotificationsHost() {\n\tconst items = useNotifications();\n\tconst { dismiss } = useNotify();\n\n\treturn (\n\t\t<div className={styles.container} aria-label=\"Область уведомлений\" aria-live=\"polite\" aria-relevant=\"additions text\">\n\t\t\t{items.map((notification) => {\n\t\t\t\tconst config = notificationConfig[notification.type];\n\t\t\t\tconst title = notification.title ?? config.title;\n\t\t\t\tconst Icon = config.Icon;\n\n\t\t\t\treturn (\n\t\t\t\t\t<article\n\t\t\t\t\t\tkey={notification.id}\n\t\t\t\t\t\trole={notification.type === \"error\" ? \"alert\" : \"status\"}\n\t\t\t\t\t\taria-atomic=\"true\"\n\t\t\t\t\t\tclassName={cn(styles.card, styles[notification.type])}>\n\t\t\t\t\t\t<FlexContainer align=\"start\" justify=\"between\" gap=\"sm\" className={styles.header}>\n\t\t\t\t\t\t\t<FlexContainer align=\"start\" gap=\"sm\" className={styles.content}>\n\t\t\t\t\t\t\t\t<span className={styles.icon} aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t<Icon />\n\t\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t\t<div className={styles.copy}>\n\t\t\t\t\t\t\t\t\t<div className={styles.kicker}>{config.title}</div>\n\t\t\t\t\t\t\t\t\t{notification.title ? <div className={styles.title}>{title}</div> : null}\n\t\t\t\t\t\t\t\t\t<div className={styles.message}>{notification.message}</div>\n\n\t\t\t\t\t\t\t\t\t{notification.actions?.length ? (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.actions}>\n\t\t\t\t\t\t\t\t\t\t\t{notification.actions.map((action) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={action.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\ttone={action.tone ?? notification.type}\n\t\t\t\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-ui=\"notification-action-button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata-action=\"notification-action\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => void action.onClick()}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</FlexContainer>\n\n\t\t\t\t\t\t\t{notification.dismissible !== false ? (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ticon={<XIcon />}\n\t\t\t\t\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\t\t\t\t\ttone={notification.type}\n\t\t\t\t\t\t\t\t\tonClick={() => dismiss(notification.id)}\n\t\t\t\t\t\t\t\t\taria-label=\"Закрыть уведомление\"\n\t\t\t\t\t\t\t\t\tdata-ui=\"notification-dismiss-button\"\n\t\t\t\t\t\t\t\t\tdata-action=\"dismiss-notification\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t</article>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|